GUIConfiguration.cpp 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431
  1. //---------------------------------------------------------------------------
  2. #include <WinPCH.h>
  3. #pragma hdrstop
  4. #include "GUIConfiguration.h"
  5. #include <FileInfo.h>
  6. #include <Terminal.h>
  7. #include <shlobj.h>
  8. //---------------------------------------------------------------------------
  9. const int ccLocal = ccUser;
  10. const int ccShowResults = ccUser << 1;
  11. const int ccCopyResults = ccUser << 2;
  12. const int ccRemoteFiles = ccUser << 3;
  13. const int ccShowResultsInMsgBox = ccUser << 4;
  14. const int ccSet = 0x80000000;
  15. const int SessionReopenAutoIdleDefault = 9000;
  16. //---------------------------------------------------------------------------
  17. static const unsigned int AdditionalLanguageMask = 0xFFFFFF00;
  18. static const UnicodeString AdditionalLanguagePrefix(L"XX");
  19. static const UnicodeString TranslationsSubFolder(L"Translations");
  20. //---------------------------------------------------------------------------
  21. TGUIConfiguration * GUIConfiguration = NULL;
  22. //---------------------------------------------------------------------------
  23. __fastcall TGUICopyParamType::TGUICopyParamType()
  24. : TCopyParamType()
  25. {
  26. GUIDefault();
  27. }
  28. //---------------------------------------------------------------------------
  29. __fastcall TGUICopyParamType::TGUICopyParamType(const TCopyParamType & Source)
  30. : TCopyParamType(Source)
  31. {
  32. GUIDefault();
  33. }
  34. //---------------------------------------------------------------------------
  35. __fastcall TGUICopyParamType::TGUICopyParamType(const TGUICopyParamType & Source)
  36. : TCopyParamType(Source)
  37. {
  38. GUIAssign(&Source);
  39. }
  40. //---------------------------------------------------------------------------
  41. void __fastcall TGUICopyParamType::Assign(const TCopyParamType * Source)
  42. {
  43. TCopyParamType::Assign(Source);
  44. const TGUICopyParamType * GUISource;
  45. GUISource = dynamic_cast<const TGUICopyParamType *>(Source);
  46. if (GUISource != NULL)
  47. {
  48. GUIAssign(GUISource);
  49. }
  50. }
  51. //---------------------------------------------------------------------------
  52. void __fastcall TGUICopyParamType::GUIAssign(const TGUICopyParamType * Source)
  53. {
  54. Queue = Source->Queue;
  55. QueueNoConfirmation = Source->QueueNoConfirmation;
  56. QueueParallel = Source->QueueParallel;
  57. }
  58. //---------------------------------------------------------------------------
  59. void __fastcall TGUICopyParamType::Default()
  60. {
  61. TCopyParamType::Default();
  62. GUIDefault();
  63. }
  64. //---------------------------------------------------------------------------
  65. void __fastcall TGUICopyParamType::GUIDefault()
  66. {
  67. Queue = false;
  68. QueueNoConfirmation = true;
  69. QueueParallel = true;
  70. }
  71. //---------------------------------------------------------------------------
  72. void __fastcall TGUICopyParamType::Load(THierarchicalStorage * Storage)
  73. {
  74. TCopyParamType::Load(Storage);
  75. Queue = Storage->ReadBool(L"Queue", Queue);
  76. QueueNoConfirmation = Storage->ReadBool(L"QueueNoConfirmation", QueueNoConfirmation);
  77. QueueParallel = Storage->ReadBool(L"QueueParallel", QueueParallel);
  78. }
  79. //---------------------------------------------------------------------------
  80. void __fastcall TGUICopyParamType::Save(THierarchicalStorage * Storage, const TCopyParamType * Defaults) const
  81. {
  82. DebugAssert(Defaults == NULL);
  83. TCopyParamType::Save(Storage, Defaults);
  84. Storage->WriteBool(L"Queue", Queue);
  85. Storage->WriteBool(L"QueueNoConfirmation", QueueNoConfirmation);
  86. Storage->WriteBool(L"QueueParallel", QueueParallel);
  87. }
  88. //---------------------------------------------------------------------------
  89. TGUICopyParamType & __fastcall TGUICopyParamType::operator =(const TCopyParamType & rhp)
  90. {
  91. Assign(&rhp);
  92. return *this;
  93. }
  94. //---------------------------------------------------------------------------
  95. TGUICopyParamType & __fastcall TGUICopyParamType::operator =(const TGUICopyParamType & rhp)
  96. {
  97. Assign(&rhp);
  98. return *this;
  99. }
  100. //---------------------------------------------------------------------------
  101. //---------------------------------------------------------------------------
  102. void __fastcall TCopyParamRuleData::Default()
  103. {
  104. HostName = L"";
  105. UserName = L"";
  106. RemoteDirectory = L"";
  107. LocalDirectory = L"";
  108. }
  109. //---------------------------------------------------------------------------
  110. //---------------------------------------------------------------------------
  111. __fastcall TCopyParamRule::TCopyParamRule()
  112. {
  113. }
  114. //---------------------------------------------------------------------------
  115. __fastcall TCopyParamRule::TCopyParamRule(const TCopyParamRuleData & Data)
  116. {
  117. FData = Data;
  118. }
  119. //---------------------------------------------------------------------------
  120. __fastcall TCopyParamRule::TCopyParamRule(const TCopyParamRule & Source)
  121. {
  122. FData.HostName = Source.FData.HostName;
  123. FData.UserName = Source.FData.UserName;
  124. FData.RemoteDirectory = Source.FData.RemoteDirectory;
  125. FData.LocalDirectory = Source.FData.LocalDirectory;
  126. }
  127. //---------------------------------------------------------------------------
  128. #define C(Property) (Property == rhp.Property)
  129. bool __fastcall TCopyParamRule::operator==(const TCopyParamRule & rhp) const
  130. {
  131. return
  132. C(FData.HostName) &&
  133. C(FData.UserName) &&
  134. C(FData.RemoteDirectory) &&
  135. C(FData.LocalDirectory) &&
  136. true;
  137. }
  138. #undef C
  139. //---------------------------------------------------------------------------
  140. bool __fastcall TCopyParamRule::Match(const UnicodeString & Mask,
  141. const UnicodeString & Value, bool Path, bool Local, int ForceDirectoryMasks) const
  142. {
  143. bool Result;
  144. if (Mask.IsEmpty())
  145. {
  146. Result = true;
  147. }
  148. else
  149. {
  150. TFileMasks M(ForceDirectoryMasks);
  151. M.Masks = Mask;
  152. if (Path)
  153. {
  154. Result = M.Matches(Value, Local, true);
  155. }
  156. else
  157. {
  158. Result = M.MatchesFileName(Value);
  159. }
  160. }
  161. return Result;
  162. }
  163. //---------------------------------------------------------------------------
  164. bool __fastcall TCopyParamRule::Matches(const TCopyParamRuleData & Value) const
  165. {
  166. return
  167. Match(FData.HostName, Value.HostName, false, true, 0) &&
  168. Match(FData.UserName, Value.UserName, false, true, 0) &&
  169. Match(FData.RemoteDirectory, Value.RemoteDirectory, true, false, 1) &&
  170. Match(FData.LocalDirectory, Value.LocalDirectory, true, true, 1);
  171. }
  172. //---------------------------------------------------------------------------
  173. void __fastcall TCopyParamRule::Load(THierarchicalStorage * Storage)
  174. {
  175. FData.HostName = Storage->ReadString(L"HostName", FData.HostName);
  176. FData.UserName = Storage->ReadString(L"UserName", FData.UserName);
  177. FData.RemoteDirectory = Storage->ReadString(L"RemoteDirectory", FData.RemoteDirectory);
  178. FData.LocalDirectory = Storage->ReadString(L"LocalDirectory", FData.LocalDirectory);
  179. }
  180. //---------------------------------------------------------------------------
  181. void __fastcall TCopyParamRule::Save(THierarchicalStorage * Storage) const
  182. {
  183. Storage->WriteString(L"HostName", FData.HostName);
  184. Storage->WriteString(L"UserName", FData.UserName);
  185. Storage->WriteString(L"RemoteDirectory", FData.RemoteDirectory);
  186. Storage->WriteString(L"LocalDirectory", FData.LocalDirectory);
  187. }
  188. //---------------------------------------------------------------------------
  189. bool __fastcall TCopyParamRule::GetEmpty() const
  190. {
  191. return
  192. FData.HostName.IsEmpty() &&
  193. FData.UserName.IsEmpty() &&
  194. FData.RemoteDirectory.IsEmpty() &&
  195. FData.LocalDirectory.IsEmpty();
  196. }
  197. //---------------------------------------------------------------------------
  198. UnicodeString __fastcall TCopyParamRule::GetInfoStr(UnicodeString Separator) const
  199. {
  200. UnicodeString Result;
  201. #define ADD(FMT, ELEM) \
  202. if (!FData.ELEM.IsEmpty()) \
  203. Result += (Result.IsEmpty() ? UnicodeString() : Separator) + FMTLOAD(FMT, (FData.ELEM));
  204. ADD(COPY_RULE_HOSTNAME, HostName);
  205. ADD(COPY_RULE_USERNAME, UserName);
  206. ADD(COPY_RULE_REMOTE_DIR, RemoteDirectory);
  207. ADD(COPY_RULE_LOCAL_DIR, LocalDirectory);
  208. #undef ADD
  209. return Result;
  210. }
  211. //---------------------------------------------------------------------------
  212. //---------------------------------------------------------------------------
  213. UnicodeString TCopyParamList::FInvalidChars(L"/\\[]");
  214. //---------------------------------------------------------------------------
  215. __fastcall TCopyParamList::TCopyParamList()
  216. {
  217. Init();
  218. }
  219. //---------------------------------------------------------------------------
  220. void __fastcall TCopyParamList::Init()
  221. {
  222. FCopyParams = new TList();
  223. FRules = new TList();
  224. FNames = new TStringList();
  225. FNameList = NULL;
  226. FModified = false;
  227. }
  228. //---------------------------------------------------------------------------
  229. __fastcall TCopyParamList::~TCopyParamList()
  230. {
  231. Clear();
  232. delete FCopyParams;
  233. delete FRules;
  234. delete FNames;
  235. delete FNameList;
  236. }
  237. //---------------------------------------------------------------------------
  238. void __fastcall TCopyParamList::Reset()
  239. {
  240. SAFE_DESTROY(FNameList);
  241. FModified = false;
  242. }
  243. //---------------------------------------------------------------------
  244. void __fastcall TCopyParamList::Modify()
  245. {
  246. SAFE_DESTROY(FNameList);
  247. FModified = true;
  248. }
  249. //---------------------------------------------------------------------
  250. void __fastcall TCopyParamList::ValidateName(const UnicodeString Name)
  251. {
  252. if (Name.LastDelimiter(FInvalidChars) > 0)
  253. {
  254. throw Exception(FMTLOAD(ITEM_NAME_INVALID, (Name, FInvalidChars)));
  255. }
  256. }
  257. //---------------------------------------------------------------------------
  258. TCopyParamList & __fastcall TCopyParamList::operator=(const TCopyParamList & rhl)
  259. {
  260. Clear();
  261. for (int Index = 0; Index < rhl.Count; Index++)
  262. {
  263. TCopyParamType * CopyParam = new TCopyParamType(*rhl.CopyParams[Index]);
  264. TCopyParamRule * Rule = NULL;
  265. if (rhl.Rules[Index] != NULL)
  266. {
  267. Rule = new TCopyParamRule(*rhl.Rules[Index]);
  268. }
  269. Add(rhl.Names[Index], CopyParam, Rule);
  270. }
  271. // there should be comparison of with the assigned list, but we rely on caller
  272. // to do it instead (TGUIConfiguration::SetCopyParamList)
  273. Modify();
  274. return *this;
  275. }
  276. //---------------------------------------------------------------------------
  277. bool __fastcall TCopyParamList::operator==(const TCopyParamList & rhl) const
  278. {
  279. bool Result = (Count == rhl.Count);
  280. if (Result)
  281. {
  282. int i = 0;
  283. while ((i < Count) && Result)
  284. {
  285. Result =
  286. (Names[i] == rhl.Names[i]) &&
  287. CompareItem(i, rhl.CopyParams[i], rhl.Rules[i]);
  288. i++;
  289. }
  290. }
  291. return Result;
  292. }
  293. //---------------------------------------------------------------------------
  294. int __fastcall TCopyParamList::IndexOfName(const UnicodeString Name) const
  295. {
  296. return FNames->IndexOf(Name);
  297. }
  298. //---------------------------------------------------------------------------
  299. bool __fastcall TCopyParamList::CompareItem(int Index,
  300. const TCopyParamType * CopyParam, const TCopyParamRule * Rule) const
  301. {
  302. return
  303. ((*CopyParams[Index]) == *CopyParam) &&
  304. ((Rules[Index] == NULL) ?
  305. (Rule == NULL) :
  306. ((Rule != NULL) && (*Rules[Index]) == (*Rule)));
  307. }
  308. //---------------------------------------------------------------------------
  309. void __fastcall TCopyParamList::Clear()
  310. {
  311. for (int i = 0; i < Count; i++)
  312. {
  313. delete CopyParams[i];
  314. delete Rules[i];
  315. }
  316. FCopyParams->Clear();
  317. FRules->Clear();
  318. FNames->Clear();
  319. }
  320. //---------------------------------------------------------------------------
  321. void __fastcall TCopyParamList::Add(const UnicodeString Name,
  322. TCopyParamType * CopyParam, TCopyParamRule * Rule)
  323. {
  324. Insert(Count, Name, CopyParam, Rule);
  325. }
  326. //---------------------------------------------------------------------------
  327. void __fastcall TCopyParamList::Insert(int Index, const UnicodeString Name,
  328. TCopyParamType * CopyParam, TCopyParamRule * Rule)
  329. {
  330. DebugAssert(FNames->IndexOf(Name) < 0);
  331. FNames->Insert(Index, Name);
  332. DebugAssert(CopyParam != NULL);
  333. FCopyParams->Insert(Index, reinterpret_cast<TObject *>(CopyParam));
  334. FRules->Insert(Index, reinterpret_cast<TObject *>(Rule));
  335. Modify();
  336. }
  337. //---------------------------------------------------------------------------
  338. void __fastcall TCopyParamList::Change(int Index, const UnicodeString Name,
  339. TCopyParamType * CopyParam, TCopyParamRule * Rule)
  340. {
  341. if ((Name != Names[Index]) || !CompareItem(Index, CopyParam, Rule))
  342. {
  343. FNames->Strings[Index] = Name;
  344. delete CopyParams[Index];
  345. FCopyParams->Items[Index] = (reinterpret_cast<TObject *>(CopyParam));
  346. delete Rules[Index];
  347. FRules->Items[Index] = (reinterpret_cast<TObject *>(Rule));
  348. Modify();
  349. }
  350. else
  351. {
  352. delete CopyParam;
  353. delete Rule;
  354. }
  355. }
  356. //---------------------------------------------------------------------------
  357. void __fastcall TCopyParamList::Move(int CurIndex, int NewIndex)
  358. {
  359. if (CurIndex != NewIndex)
  360. {
  361. FNames->Move(CurIndex, NewIndex);
  362. FCopyParams->Move(CurIndex, NewIndex);
  363. FRules->Move(CurIndex, NewIndex);
  364. Modify();
  365. }
  366. }
  367. //---------------------------------------------------------------------------
  368. void __fastcall TCopyParamList::Delete(int Index)
  369. {
  370. DebugAssert((Index >= 0) && (Index < Count));
  371. FNames->Delete(Index);
  372. delete CopyParams[Index];
  373. FCopyParams->Delete(Index);
  374. delete Rules[Index];
  375. FRules->Delete(Index);
  376. Modify();
  377. }
  378. //---------------------------------------------------------------------------
  379. int __fastcall TCopyParamList::Find(const TCopyParamRuleData & Value) const
  380. {
  381. int Result = -1;
  382. int i = 0;
  383. while ((i < FRules->Count) && (Result < 0))
  384. {
  385. if (FRules->Items[i] != NULL)
  386. {
  387. if (Rules[i]->Matches(Value))
  388. {
  389. Result = i;
  390. }
  391. }
  392. i++;
  393. }
  394. return Result;
  395. }
  396. //---------------------------------------------------------------------------
  397. void __fastcall TCopyParamList::Load(THierarchicalStorage * Storage, int ACount)
  398. {
  399. for (int Index = 0; Index < ACount; Index++)
  400. {
  401. UnicodeString Name = IntToStr(Index);
  402. TCopyParamRule * Rule = NULL;
  403. TCopyParamType * CopyParam = new TCopyParamType();
  404. try
  405. {
  406. if (Storage->OpenSubKey(Name, false))
  407. {
  408. try
  409. {
  410. Name = Storage->ReadString(L"Name", Name);
  411. CopyParam->Load(Storage);
  412. if (Storage->ReadBool(L"HasRule", false))
  413. {
  414. Rule = new TCopyParamRule();
  415. Rule->Load(Storage);
  416. }
  417. }
  418. __finally
  419. {
  420. Storage->CloseSubKey();
  421. }
  422. }
  423. }
  424. catch(...)
  425. {
  426. delete CopyParam;
  427. delete Rule;
  428. throw;
  429. }
  430. FCopyParams->Add(reinterpret_cast<TObject *>(CopyParam));
  431. FRules->Add(reinterpret_cast<TObject *>(Rule));
  432. FNames->Add(Name);
  433. }
  434. Reset();
  435. }
  436. //---------------------------------------------------------------------------
  437. void __fastcall TCopyParamList::Save(THierarchicalStorage * Storage) const
  438. {
  439. Storage->ClearSubKeys();
  440. for (int Index = 0; Index < Count; Index++)
  441. {
  442. if (Storage->OpenSubKey(IntToStr(Index), true))
  443. {
  444. try
  445. {
  446. const TCopyParamType * CopyParam = CopyParams[Index];
  447. const TCopyParamRule * Rule = Rules[Index];
  448. Storage->WriteString(L"Name", Names[Index]);
  449. CopyParam->Save(Storage);
  450. Storage->WriteBool(L"HasRule", (Rule != NULL));
  451. if (Rule != NULL)
  452. {
  453. Rule->Save(Storage);
  454. }
  455. }
  456. __finally
  457. {
  458. Storage->CloseSubKey();
  459. }
  460. }
  461. }
  462. }
  463. //---------------------------------------------------------------------------
  464. int __fastcall TCopyParamList::GetCount() const
  465. {
  466. return FCopyParams->Count;
  467. }
  468. //---------------------------------------------------------------------------
  469. const TCopyParamRule * __fastcall TCopyParamList::GetRule(int Index) const
  470. {
  471. return reinterpret_cast<TCopyParamRule *>(FRules->Items[Index]);
  472. }
  473. //---------------------------------------------------------------------------
  474. const TCopyParamType * __fastcall TCopyParamList::GetCopyParam(int Index) const
  475. {
  476. return reinterpret_cast<TCopyParamType *>(FCopyParams->Items[Index]);
  477. }
  478. //---------------------------------------------------------------------------
  479. UnicodeString __fastcall TCopyParamList::GetName(int Index) const
  480. {
  481. return FNames->Strings[Index];
  482. }
  483. //---------------------------------------------------------------------------
  484. TStrings * __fastcall TCopyParamList::GetNameList() const
  485. {
  486. if (FNameList == NULL)
  487. {
  488. FNameList = new TStringList();
  489. for (int i = 0; i < Count; i++)
  490. {
  491. FNameList->Add(FNames->Strings[i]);
  492. }
  493. }
  494. return FNameList;
  495. }
  496. //---------------------------------------------------------------------------
  497. bool __fastcall TCopyParamList::GetAnyRule() const
  498. {
  499. bool Result = false;
  500. int i = 0;
  501. while ((i < Count) && !Result)
  502. {
  503. Result = (Rules[i] != NULL);
  504. i++;
  505. }
  506. return Result;
  507. }
  508. //---------------------------------------------------------------------------
  509. //---------------------------------------------------------------------------
  510. __fastcall TGUIConfiguration::TGUIConfiguration(): TConfiguration()
  511. {
  512. FLocale = 0;
  513. SetAppliedLocale(InternalLocale(), UnicodeString());
  514. FLocales = new TObjectList();
  515. FLastLocalesExts = L"*";
  516. FCopyParamList = new TCopyParamList();
  517. CoreSetResourceModule(GetResourceModule());
  518. }
  519. //---------------------------------------------------------------------------
  520. __fastcall TGUIConfiguration::~TGUIConfiguration()
  521. {
  522. delete FLocales;
  523. delete FCopyParamList;
  524. }
  525. //---------------------------------------------------------------------------
  526. void __fastcall TGUIConfiguration::Default()
  527. {
  528. TConfiguration::Default();
  529. // reset before call to DefaultLocalized()
  530. FDefaultCopyParam.Default();
  531. FCopyParamListDefaults = true;
  532. DefaultLocalized();
  533. FIgnoreCancelBeforeFinish = TDateTime(0, 0, 3, 0);
  534. FContinueOnError = false;
  535. FConfirmCommandSession = true;
  536. FSynchronizeParams = TTerminal::spDefault;
  537. FSynchronizeModeAuto = -1;
  538. FSynchronizeMode = TTerminal::smRemote;
  539. FMaxWatchDirectories = 500;
  540. FSynchronizeOptions = soRecurse | soSynchronizeAsk;
  541. FQueueBootstrap = false;
  542. FQueueKeepDoneItems = true;
  543. FQueueKeepDoneItemsFor = 15;
  544. FQueueAutoPopup = true;
  545. FSessionRememberPassword = true;
  546. UnicodeString ProgramsFolder;
  547. ::SpecialFolderLocation(CSIDL_PROGRAM_FILES, ProgramsFolder);
  548. FDefaultPuttyPathOnly = IncludeTrailingBackslash(ProgramsFolder) + L"PuTTY\\" + OriginalPuttyExecutable;
  549. FDefaultPuttyPath = L"%ProgramFiles%\\PuTTY\\" + OriginalPuttyExecutable;
  550. FPuttyPath = FormatCommand(FDefaultPuttyPath, L"");
  551. FUsePuttyPwFile = asAuto;
  552. FPuttyPassword = false;
  553. FTelnetForFtpInPutty = true;
  554. FPuttySession = L"WinSCP temporary session";
  555. FBeepOnFinish = false;
  556. FBeepOnFinishAfter = TDateTime(0, 0, 30, 0);
  557. FBeepSound = L"SystemDefault";
  558. FCopyParamCurrent = L"";
  559. FKeepUpToDateChangeDelay = 500;
  560. FChecksumAlg = L"sha1";
  561. FSessionReopenAutoIdle = SessionReopenAutoIdleDefault;
  562. FSessionReopenAutoIdleOn = true;
  563. FSessionReopenAutoInactive = false;
  564. FNewDirectoryProperties.Default();
  565. FNewDirectoryProperties.Rights = TRights::rfDefault | TRights::rfExec;
  566. }
  567. //---------------------------------------------------------------------------
  568. void __fastcall TGUIConfiguration::DefaultLocalized()
  569. {
  570. if (FCopyParamListDefaults)
  571. {
  572. FCopyParamList->Clear();
  573. // guard against "empty resource string" from obsolete traslations
  574. // (DefaultLocalized is called for the first time before detection of
  575. // obsolete translations)
  576. if (!LoadStr(COPY_PARAM_PRESET_ASCII).IsEmpty())
  577. {
  578. TCopyParamType * CopyParam;
  579. CopyParam = new TCopyParamType(FDefaultCopyParam);
  580. CopyParam->TransferMode = tmAscii;
  581. FCopyParamList->Add(LoadStr(COPY_PARAM_PRESET_ASCII), CopyParam, NULL);
  582. CopyParam = new TCopyParamType(FDefaultCopyParam);
  583. CopyParam->TransferMode = tmBinary;
  584. FCopyParamList->Add(LoadStr(COPY_PARAM_PRESET_BINARY), CopyParam, NULL);
  585. CopyParam = new TCopyParamType(FDefaultCopyParam);
  586. CopyParam->NewerOnly = true;
  587. FCopyParamList->Add(LoadStr(COPY_PARAM_NEWER_ONLY), CopyParam, NULL);
  588. CopyParam = new TCopyParamType(FDefaultCopyParam);
  589. CopyParam->IncludeFileMask = TFileMasks(FORMAT(L"%s */", (IncludeExcludeFileMasksDelimiter)));
  590. FCopyParamList->Add(LoadStr(COPY_PARAM_PRESET_EXCLUDE_ALL_DIR), CopyParam, NULL);
  591. }
  592. FCopyParamList->Reset();
  593. }
  594. }
  595. //---------------------------------------------------------------------------
  596. void __fastcall TGUIConfiguration::UpdateStaticUsage()
  597. {
  598. TConfiguration::UpdateStaticUsage();
  599. Usage->Set(L"CopyParamsCount", (FCopyParamListDefaults ? 0 : FCopyParamList->Count));
  600. Usage->Set(L"Putty", ExtractProgramName(PuttyPath));
  601. }
  602. //---------------------------------------------------------------------------
  603. // duplicated from core\configuration.cpp
  604. #define BLOCK(KEY, CANCREATE, BLOCK) \
  605. if (Storage->OpenSubKeyPath(KEY, CANCREATE)) try { BLOCK } __finally { Storage->CloseSubKeyPath(); }
  606. #define KEY(TYPE, VAR) KEYEX(TYPE, VAR, PropertyToKey(TEXT(#VAR)))
  607. #define REGCONFIG(CANCREATE) \
  608. BLOCK(L"Interface", CANCREATE, \
  609. KEY(Bool, ContinueOnError); \
  610. KEY(Bool, ConfirmCommandSession); \
  611. KEY(Integer, SynchronizeParams); \
  612. KEY(Integer, SynchronizeOptions); \
  613. KEY(Integer, SynchronizeModeAuto); \
  614. KEY(Integer, SynchronizeMode); \
  615. KEY(Integer, MaxWatchDirectories); \
  616. KEY(Bool, QueueBootstrap); \
  617. KEY(Integer, QueueKeepDoneItems); \
  618. KEY(Integer, QueueKeepDoneItemsFor); \
  619. KEY(Bool, QueueAutoPopup); \
  620. KEYEX(Bool, SessionRememberPassword, L"QueueRememberPassword"); \
  621. KEY(String, PuttySession); \
  622. KEY(String, PuttyPath); \
  623. KEY(Enum, UsePuttyPwFile); \
  624. KEY(Bool, PuttyPassword); \
  625. KEY(Bool, TelnetForFtpInPutty); \
  626. KEY(DateTime, IgnoreCancelBeforeFinish); \
  627. KEY(Bool, BeepOnFinish); \
  628. KEY(DateTime, BeepOnFinishAfter); \
  629. KEY(String, BeepSound); \
  630. KEY(Integer, KeepUpToDateChangeDelay); \
  631. KEY(String, ChecksumAlg); \
  632. KEY(Integer, SessionReopenAutoIdle); \
  633. KEY(Bool, SessionReopenAutoIdleOn); \
  634. KEY(Bool, SessionReopenAutoInactive); \
  635. ); \
  636. //---------------------------------------------------------------------------
  637. bool __fastcall TGUIConfiguration::DoSaveCopyParam(THierarchicalStorage * Storage, const TCopyParamType * CopyParam, const TCopyParamType * Defaults)
  638. {
  639. bool Result = Storage->OpenSubKeyPath(L"Interface\\CopyParam", true);
  640. if (Result)
  641. {
  642. CopyParam->Save(Storage, Defaults);
  643. }
  644. return Result;
  645. }
  646. //---------------------------------------------------------------------------
  647. void __fastcall TGUIConfiguration::SaveData(THierarchicalStorage * Storage, bool All)
  648. {
  649. TConfiguration::SaveData(Storage, All);
  650. // duplicated from core\configuration.cpp
  651. #define KEYEX(TYPE, VAR, NAME) Storage->Write ## TYPE(NAME, VAR)
  652. REGCONFIG(true);
  653. #undef KEYEX
  654. if (DoSaveCopyParam(Storage, &FDefaultCopyParam, NULL))
  655. try
  656. {
  657. FDefaultCopyParam.Save(Storage);
  658. if (FCopyParamListDefaults)
  659. {
  660. DebugAssert(!FCopyParamList->Modified);
  661. Storage->WriteInteger(L"CopyParamList", -1);
  662. }
  663. else if (All || FCopyParamList->Modified)
  664. {
  665. Storage->WriteInteger(L"CopyParamList", FCopyParamList->Count);
  666. FCopyParamList->Save(Storage);
  667. }
  668. }
  669. __finally
  670. {
  671. Storage->CloseSubKeyPath();
  672. }
  673. if (Storage->OpenSubKeyPath(L"Interface\\NewDirectory2", true))
  674. try
  675. {
  676. FNewDirectoryProperties.Save(Storage);
  677. }
  678. __finally
  679. {
  680. Storage->CloseSubKeyPath();
  681. }
  682. }
  683. //---------------------------------------------------------------------------
  684. bool __fastcall TGUIConfiguration::LoadCopyParam(THierarchicalStorage * Storage, TCopyParamType * CopyParam)
  685. {
  686. bool Result =
  687. Storage->OpenSubKeyPath(L"Interface\\CopyParam", false);
  688. if (Result)
  689. {
  690. try
  691. {
  692. CopyParam->Load(Storage);
  693. }
  694. catch (...)
  695. {
  696. Storage->CloseSubKeyPath();
  697. throw;
  698. }
  699. }
  700. return Result;
  701. }
  702. //---------------------------------------------------------------------------
  703. void __fastcall TGUIConfiguration::LoadDefaultCopyParam(THierarchicalStorage * Storage)
  704. {
  705. FDefaultCopyParam.Load(Storage);
  706. }
  707. //---------------------------------------------------------------------------
  708. void __fastcall TGUIConfiguration::LoadData(THierarchicalStorage * Storage)
  709. {
  710. TConfiguration::LoadData(Storage);
  711. // duplicated from core\configuration.cpp
  712. #define KEYEX(TYPE, VAR, NAME) VAR = Storage->Read ## TYPE(NAME, VAR)
  713. #pragma warn -eas
  714. REGCONFIG(false);
  715. #pragma warn +eas
  716. #undef KEYEX
  717. // FDefaultCopyParam must be loaded before eventual setting defaults for CopyParamList
  718. if (LoadCopyParam(Storage, &FDefaultCopyParam))
  719. try
  720. {
  721. int CopyParamListCount = Storage->ReadInteger(L"CopyParamList", -1);
  722. FCopyParamListDefaults = (CopyParamListCount < 0);
  723. if (!FCopyParamListDefaults)
  724. {
  725. FCopyParamList->Clear();
  726. FCopyParamList->Load(Storage, CopyParamListCount);
  727. }
  728. else if (FCopyParamList->Modified)
  729. {
  730. FCopyParamList->Clear();
  731. FCopyParamListDefaults = false;
  732. }
  733. FCopyParamList->Reset();
  734. }
  735. __finally
  736. {
  737. Storage->CloseSubKeyPath();
  738. }
  739. // Make it compatible with versions prior to 3.7.1 that have not saved PuttyPath
  740. // with quotes. First check for absence of quotes.
  741. // Add quotes either if the path is set to default putty path (even if it does
  742. // not exists) or when the path points to existing file (so there are no parameters
  743. // yet in the string). Note that FileExists may display error dialog, but as
  744. // it should be called only for custom users path, let's expect that the user
  745. // can take care of it.
  746. if ((FPuttyPath.SubString(1, 1) != L"\"") &&
  747. (IsPathToSameFile(ExpandEnvironmentVariables(FPuttyPath), FDefaultPuttyPathOnly) ||
  748. FileExists(ApiPath(ExpandEnvironmentVariables(FPuttyPath)))))
  749. {
  750. FPuttyPath = FormatCommand(FPuttyPath, L"");
  751. }
  752. if (Storage->OpenSubKeyPath(L"Interface\\NewDirectory2", false))
  753. try
  754. {
  755. FNewDirectoryProperties.Load(Storage);
  756. }
  757. __finally
  758. {
  759. Storage->CloseSubKeyPath();
  760. }
  761. }
  762. //---------------------------------------------------------------------------
  763. void __fastcall TGUIConfiguration::Saved()
  764. {
  765. TConfiguration::Saved();
  766. FCopyParamList->Reset();
  767. }
  768. //---------------------------------------------------------------------------
  769. //---------------------------------------------------------------------------
  770. UnicodeString __fastcall TGUIConfiguration::GetTranslationModule(const UnicodeString & Path)
  771. {
  772. UnicodeString SubPath =
  773. TPath::Combine(TPath::Combine(ExtractFilePath(Path), TranslationsSubFolder), ExtractFileName(Path));
  774. UnicodeString Result;
  775. // Prefer the SubPath. Default to SubPath.
  776. if (FileExists(Path) && !FileExists(SubPath))
  777. {
  778. Result = Path;
  779. }
  780. else
  781. {
  782. Result = SubPath;
  783. }
  784. return Result;
  785. }
  786. //---------------------------------------------------------------------------
  787. HINSTANCE __fastcall TGUIConfiguration::LoadNewResourceModule(LCID ALocale,
  788. UnicodeString & FileName)
  789. {
  790. UnicodeString LibraryFileName;
  791. HINSTANCE NewInstance = 0;
  792. LCID AInternalLocale = InternalLocale();
  793. bool Internal = (ALocale == AInternalLocale);
  794. DWORD PrimaryLang = PRIMARYLANGID(ALocale);
  795. if (!Internal)
  796. {
  797. UnicodeString Module;
  798. UnicodeString LocaleName;
  799. Module = ModuleFileName();
  800. if ((ALocale & AdditionalLanguageMask) != AdditionalLanguageMask)
  801. {
  802. wchar_t LocaleStr[4];
  803. GetLocaleInfo(ALocale, LOCALE_SABBREVLANGNAME, LocaleStr, LENOF(LocaleStr));
  804. LocaleName = LocaleStr;
  805. DebugAssert(!LocaleName.IsEmpty());
  806. }
  807. else
  808. {
  809. LocaleName = AdditionalLanguagePrefix +
  810. char(ALocale & ~AdditionalLanguageMask);
  811. }
  812. Module = ChangeFileExt(Module, UnicodeString(L".") + LocaleName);
  813. // Look for a potential language/country translation
  814. UnicodeString ModulePath = GetTranslationModule(Module);
  815. NewInstance = LoadLibraryEx(ModulePath.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE);
  816. if (NewInstance)
  817. {
  818. LibraryFileName = ModulePath;
  819. }
  820. else
  821. {
  822. DWORD SubLang = SUBLANGID(ALocale);
  823. DebugAssert(SUBLANG_DEFAULT == SUBLANG_CHINESE_TRADITIONAL);
  824. // Finally look for a language-only translation.
  825. // But for Chinese, never use "traditional" (what is the "default" Chinese), if we want "Simplified"
  826. // (the same what Inno Setup does)
  827. if ((PrimaryLang != LANG_CHINESE) ||
  828. (SubLang == SUBLANG_CHINESE_TRADITIONAL))
  829. {
  830. Module.SetLength(Module.Length() - 1);
  831. ModulePath = GetTranslationModule(Module);
  832. NewInstance = LoadLibraryEx(ModulePath.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE);
  833. if (NewInstance)
  834. {
  835. LibraryFileName = ModulePath;
  836. }
  837. }
  838. }
  839. }
  840. // If the locale is non-US English and we do not have that translation (and it's unlikely we ever have),
  841. // treat it as if it were US English.
  842. if (!NewInstance && !Internal && (PrimaryLang == static_cast<DWORD>(PRIMARYLANGID(AInternalLocale))))
  843. {
  844. Internal = true;
  845. }
  846. if (!NewInstance && !Internal)
  847. {
  848. throw Exception(FMTLOAD(LOCALE_LOAD_ERROR, (int(ALocale))));
  849. }
  850. else
  851. {
  852. if (Internal)
  853. {
  854. NewInstance = HInstance;
  855. }
  856. }
  857. FileName = LibraryFileName;
  858. return NewInstance;
  859. }
  860. //---------------------------------------------------------------------------
  861. LCID __fastcall TGUIConfiguration::InternalLocale()
  862. {
  863. LCID Result;
  864. if (GetTranslationCount(ApplicationInfo) > 0)
  865. {
  866. TTranslation Translation;
  867. Translation = GetTranslation(ApplicationInfo, 0);
  868. Result = MAKELANGID(PRIMARYLANGID(Translation.Language), SUBLANG_DEFAULT);
  869. }
  870. else
  871. {
  872. DebugFail();
  873. Result = 0;
  874. }
  875. return Result;
  876. }
  877. //---------------------------------------------------------------------------
  878. LCID __fastcall TGUIConfiguration::GetLocale()
  879. {
  880. return FLocale;
  881. }
  882. //---------------------------------------------------------------------------
  883. void __fastcall TGUIConfiguration::SetLocale(LCID value)
  884. {
  885. if (Locale != value)
  886. {
  887. SetLocaleInternal(value, false, false);
  888. }
  889. }
  890. //---------------------------------------------------------------------------
  891. void __fastcall TGUIConfiguration::SetLocaleSafe(LCID value)
  892. {
  893. if (Locale != value)
  894. {
  895. SetLocaleInternal(value, true, false);
  896. }
  897. }
  898. //---------------------------------------------------------------------------
  899. UnicodeString __fastcall TGUIConfiguration::GetAppliedLocaleHex()
  900. {
  901. return IntToHex(__int64(AppliedLocale), 4);
  902. }
  903. //---------------------------------------------------------------------------
  904. int __fastcall TGUIConfiguration::GetResourceModuleCompleteness(HINSTANCE /*Module*/)
  905. {
  906. return 100;
  907. }
  908. //---------------------------------------------------------------------------
  909. bool __fastcall TGUIConfiguration::IsTranslationComplete(HINSTANCE /*Module*/)
  910. {
  911. return true;
  912. }
  913. //---------------------------------------------------------------------------
  914. void __fastcall TGUIConfiguration::SetLocaleInternal(LCID value, bool Safe, bool CompleteOnly)
  915. {
  916. LCID L = value;
  917. if (L == NULL)
  918. {
  919. L = GetUserDefaultUILanguage();
  920. }
  921. HINSTANCE Module = NULL;
  922. UnicodeString FileName;
  923. try
  924. {
  925. Module = LoadNewResourceModule(L, FileName);
  926. DebugAssert(Module != NULL);
  927. if (CompleteOnly && !IsTranslationComplete(Module))
  928. {
  929. Abort();
  930. }
  931. }
  932. catch (...)
  933. {
  934. if (Module != NULL)
  935. {
  936. FreeResourceModule(Module);
  937. Module = NULL;
  938. }
  939. if (Safe)
  940. {
  941. // ignore any exception while loading locale
  942. }
  943. else
  944. {
  945. throw;
  946. }
  947. }
  948. if (Module != NULL)
  949. {
  950. FLocale = value;
  951. if (CanApplyLocaleImmediately)
  952. {
  953. SetAppliedLocale(L, FileName);
  954. SetResourceModule(Module);
  955. ResStringCleanupCache();
  956. }
  957. }
  958. }
  959. //---------------------------------------------------------------------------
  960. bool __fastcall TGUIConfiguration::GetCanApplyLocaleImmediately()
  961. {
  962. return
  963. (Screen->FormCount == 0) &&
  964. (Screen->DataModuleCount == 0);
  965. }
  966. //---------------------------------------------------------------------------
  967. bool __fastcall TGUIConfiguration::UsingInternalTranslation()
  968. {
  969. return FLocaleModuleName.IsEmpty();
  970. }
  971. //---------------------------------------------------------------------------
  972. UnicodeString __fastcall TGUIConfiguration::AppliedLocaleCopyright()
  973. {
  974. UnicodeString Result;
  975. if (UsingInternalTranslation())
  976. {
  977. DebugFail(); // we do not expect to get called with internal locale
  978. Result = UnicodeString();
  979. }
  980. else
  981. {
  982. Result = GetFileFileInfoString(L"LegalCopyright", FLocaleModuleName);
  983. }
  984. return Result;
  985. }
  986. //---------------------------------------------------------------------------
  987. UnicodeString __fastcall TGUIConfiguration::AppliedLocaleVersion()
  988. {
  989. UnicodeString Result;
  990. if (UsingInternalTranslation())
  991. {
  992. // noop
  993. }
  994. else
  995. {
  996. Result = GetFileVersion(FLocaleModuleName);
  997. }
  998. return Result;
  999. }
  1000. //---------------------------------------------------------------------------
  1001. void __fastcall TGUIConfiguration::SetAppliedLocale(LCID AppliedLocale, const UnicodeString & LocaleModuleName)
  1002. {
  1003. FAppliedLocale = AppliedLocale;
  1004. FLocaleModuleName = LocaleModuleName;
  1005. }
  1006. //---------------------------------------------------------------------------
  1007. void __fastcall TGUIConfiguration::FreeResourceModule(HANDLE Instance)
  1008. {
  1009. TLibModule * MainModule = FindModule(HInstance);
  1010. if ((unsigned)Instance != MainModule->Instance)
  1011. {
  1012. FreeLibrary(static_cast<HMODULE>(Instance));
  1013. }
  1014. }
  1015. //---------------------------------------------------------------------------
  1016. HANDLE __fastcall TGUIConfiguration::ChangeToDefaultResourceModule()
  1017. {
  1018. return ChangeResourceModule(NULL);
  1019. }
  1020. //---------------------------------------------------------------------------
  1021. HANDLE __fastcall TGUIConfiguration::ChangeResourceModule(HANDLE Instance)
  1022. {
  1023. if (Instance == NULL)
  1024. {
  1025. Instance = HInstance;
  1026. }
  1027. TLibModule * MainModule = FindModule(HInstance);
  1028. HANDLE Result = (HANDLE)MainModule->ResInstance;
  1029. MainModule->ResInstance = (unsigned)Instance;
  1030. CoreSetResourceModule(Instance);
  1031. return Result;
  1032. }
  1033. //---------------------------------------------------------------------------
  1034. HANDLE __fastcall TGUIConfiguration::GetResourceModule()
  1035. {
  1036. return (HANDLE)FindModule(HInstance)->ResInstance;
  1037. }
  1038. //---------------------------------------------------------------------------
  1039. void __fastcall TGUIConfiguration::SetResourceModule(HINSTANCE Instance)
  1040. {
  1041. HANDLE PrevHandle = ChangeResourceModule(Instance);
  1042. FreeResourceModule(PrevHandle);
  1043. DefaultLocalized();
  1044. }
  1045. //---------------------------------------------------------------------------
  1046. void __fastcall TGUIConfiguration::FindLocales(const UnicodeString & Path, TStrings * Exts, UnicodeString & LocalesExts)
  1047. {
  1048. int FindAttrs = faReadOnly | faArchive;
  1049. TSearchRecOwned SearchRec;
  1050. UnicodeString BaseName = ChangeFileExt(ExtractFileName(ModuleFileName()), L".");
  1051. UnicodeString LocalesMask = TPath::Combine(Path, BaseName + L"*");
  1052. bool Found = (FindFirstUnchecked(LocalesMask, FindAttrs, SearchRec) == 0);
  1053. while (Found)
  1054. {
  1055. if (DebugAlwaysTrue(SameText(BaseName, LeftStr(SearchRec.Name, BaseName.Length()))))
  1056. {
  1057. UnicodeString Ext = MidStr(SearchRec.Name, BaseName.Length() + 1).UpperCase();
  1058. // DLL is a remnant from times the .NET assembly was winscp.dll, not winscpnet.dll.
  1059. if ((Ext.Length() >= 2) && (Ext.Length() <= 3) &&
  1060. (Ext != L"EXE") && (Ext != L"COM") && (Ext != L"DLL") && (Ext != L"INI") && (Ext != L"MAP"))
  1061. {
  1062. LocalesExts += Ext + L",";
  1063. Exts->Add(Ext);
  1064. }
  1065. }
  1066. Found = (FindNextChecked(SearchRec) == 0);
  1067. }
  1068. }
  1069. //---------------------------------------------------------------------------
  1070. void __fastcall TGUIConfiguration::AddLocale(LCID Locale, const UnicodeString & AName)
  1071. {
  1072. UnicodeString Name = AName;
  1073. if (Name.IsEmpty())
  1074. {
  1075. wchar_t LocaleStr[255];
  1076. GetLocaleInfo(Locale, LOCALE_SENGLANGUAGE, LocaleStr, LENOF(LocaleStr));
  1077. Name = UnicodeString(LocaleStr) + TitleSeparator;
  1078. // LOCALE_SNATIVELANGNAME
  1079. GetLocaleInfo(Locale, LOCALE_SLANGUAGE, LocaleStr, LENOF(LocaleStr));
  1080. Name += LocaleStr;
  1081. }
  1082. std::unique_ptr<TLocaleInfo> LocaleInfo(new TLocaleInfo());
  1083. LocaleInfo->Locale = Locale;
  1084. LocaleInfo->Name = Name;
  1085. try
  1086. {
  1087. UnicodeString FileName;
  1088. HINSTANCE Module = LoadNewResourceModule(Locale, FileName);
  1089. try
  1090. {
  1091. LocaleInfo->Completeness = GetResourceModuleCompleteness(Module);
  1092. }
  1093. __finally
  1094. {
  1095. FreeResourceModule(Module);
  1096. }
  1097. }
  1098. catch (...)
  1099. {
  1100. LocaleInfo->Completeness = -1;
  1101. }
  1102. FLocales->Add(LocaleInfo.release());
  1103. }
  1104. //---------------------------------------------------------------------------
  1105. int __fastcall TGUIConfiguration::LocalesCompare(void * Item1, void * Item2)
  1106. {
  1107. TLocaleInfo * LocaleInfo1 = static_cast<TLocaleInfo *>(Item1);
  1108. TLocaleInfo * LocaleInfo2 = static_cast<TLocaleInfo *>(Item2);
  1109. return CompareText(LocaleInfo1->Name, LocaleInfo2->Name);
  1110. }
  1111. //---------------------------------------------------------------------------
  1112. TObjectList * __fastcall TGUIConfiguration::GetLocales()
  1113. {
  1114. UnicodeString LocalesPath = ExtractFilePath(ModuleFileName());
  1115. UnicodeString SubLocalesPath = TPath::Combine(LocalesPath, TranslationsSubFolder);
  1116. UnicodeString LocalesExts;
  1117. std::unique_ptr<TStringList> Exts(CreateSortedStringList());
  1118. FindLocales(LocalesPath, Exts.get(), LocalesExts);
  1119. FindLocales(SubLocalesPath, Exts.get(), LocalesExts);
  1120. if (FLastLocalesExts != LocalesExts)
  1121. {
  1122. FLastLocalesExts = LocalesExts;
  1123. FLocales->Clear();
  1124. AddLocale(InternalLocale(), EmptyStr);
  1125. TLanguages * Langs = Languages();
  1126. int Count = Langs->Count;
  1127. typedef std::map<UnicodeString, std::pair<int, DWORD> > TConflicts;
  1128. TConflicts DefaultLangConflicts;
  1129. LCID InvalidLocale = static_cast<LCID>(-1);
  1130. // The two-leter Windows code is not actually unique among languages.
  1131. // So find any duplicities and resolve them to the language, where ISO code also match.
  1132. // Notably:
  1133. // Georgian KAT ka-GE - Kalaallisut KAL kl-GL
  1134. // Tamil TAI ta-IN - Tajik TAJ tj-TJ
  1135. for (int Index = 0; Index < Count; Index++)
  1136. {
  1137. LCID Locale = Langs->LocaleID[Index];
  1138. DWORD SubLang = SUBLANGID(Locale);
  1139. if (SubLang == SUBLANG_DEFAULT)
  1140. {
  1141. UnicodeString LangExt2 = LeftStr(Langs->Ext[Index].UpperCase(), 2);
  1142. TConflicts::iterator Conflict = DefaultLangConflicts.find(LangExt2);
  1143. if (Conflict == DefaultLangConflicts.end())
  1144. {
  1145. Conflict = DefaultLangConflicts.insert(std::make_pair(LangExt2, std::make_pair(1, InvalidLocale))).first;
  1146. }
  1147. else
  1148. {
  1149. Conflict->second.first++;
  1150. }
  1151. UnicodeString LangName = CopyToChar(Langs->LocaleName[Index], L'-', false);
  1152. bool Matches = SameText(LangName, LangExt2);
  1153. if (Matches)
  1154. {
  1155. Conflict->second.second = Locale;
  1156. }
  1157. }
  1158. }
  1159. for (int Index = 0; Index < Count; Index++)
  1160. {
  1161. LCID Locale = Langs->LocaleID[Index];
  1162. DWORD SubLang = SUBLANGID(Locale);
  1163. UnicodeString LangExt3 = Langs->Ext[Index].UpperCase();
  1164. int Ext = Exts->IndexOf(LangExt3);
  1165. if ((Ext < 0) && (SubLang == SUBLANG_DEFAULT))
  1166. {
  1167. UnicodeString LangExt2 = LeftStr(LangExt3, 2);
  1168. TConflicts::const_iterator DefaultLangConflict = DefaultLangConflicts.find(LangExt2);
  1169. // Unless it is a conflicting extension with no resolution or resolved to another locale
  1170. if ((DefaultLangConflict == DefaultLangConflicts.end()) ||
  1171. (DefaultLangConflict->second.first == 1) ||
  1172. ((DefaultLangConflict->second.second != InvalidLocale) &&
  1173. (DefaultLangConflict->second.second == Locale)))
  1174. {
  1175. Ext = Exts->IndexOf(LangExt2);
  1176. }
  1177. }
  1178. if ((Ext >= 0) && DebugAlwaysTrue(Exts->Objects[Ext] == NULL))
  1179. {
  1180. Exts->Objects[Ext] = reinterpret_cast<TObject*>(Locale);
  1181. AddLocale(Locale, EmptyStr);
  1182. }
  1183. }
  1184. for (int Index = 0; Index < Exts->Count; Index++)
  1185. {
  1186. if ((Exts->Objects[Index] == NULL) &&
  1187. (Exts->Strings[Index].Length() == 3) &&
  1188. SameText(Exts->Strings[Index].SubString(1, 2), AdditionalLanguagePrefix))
  1189. {
  1190. UnicodeString ModulePath = ChangeFileExt(ModuleFileName(), UnicodeString(L".") + Exts->Strings[Index]);
  1191. ModulePath = GetTranslationModule(ModulePath);
  1192. UnicodeString LangName = GetFileFileInfoString(L"LangName", ModulePath);
  1193. if (!LangName.IsEmpty())
  1194. {
  1195. AddLocale(AdditionalLanguageMask + Exts->Strings[Index][3], LangName);
  1196. }
  1197. }
  1198. }
  1199. FLocales->Sort(LocalesCompare);
  1200. }
  1201. return FLocales;
  1202. }
  1203. //---------------------------------------------------------------------------
  1204. void __fastcall TGUIConfiguration::SetDefaultCopyParam(const TGUICopyParamType & value)
  1205. {
  1206. FDefaultCopyParam.Assign(&value);
  1207. Changed();
  1208. }
  1209. //---------------------------------------------------------------------------
  1210. bool __fastcall TGUIConfiguration::GetRememberPassword()
  1211. {
  1212. bool Result = SessionRememberPassword || PuttyPassword;
  1213. if (!Result)
  1214. {
  1215. try
  1216. {
  1217. TRemoteCustomCommand RemoteCustomCommand;
  1218. TInteractiveCustomCommand InteractiveCustomCommand(&RemoteCustomCommand);
  1219. UnicodeString APuttyPath = InteractiveCustomCommand.Complete(PuttyPath, false);
  1220. Result = RemoteCustomCommand.IsPasswordCommand(PuttyPath);
  1221. }
  1222. catch (...)
  1223. {
  1224. // noop
  1225. }
  1226. }
  1227. return Result;
  1228. }
  1229. //---------------------------------------------------------------------------
  1230. const TCopyParamList * __fastcall TGUIConfiguration::GetCopyParamList()
  1231. {
  1232. return FCopyParamList;
  1233. }
  1234. //---------------------------------------------------------------------------
  1235. void __fastcall TGUIConfiguration::SetCopyParamList(const TCopyParamList * value)
  1236. {
  1237. if (!(*FCopyParamList == *value))
  1238. {
  1239. *FCopyParamList = *value;
  1240. FCopyParamListDefaults = false;
  1241. Changed();
  1242. }
  1243. }
  1244. //---------------------------------------------------------------------------
  1245. int __fastcall TGUIConfiguration::GetCopyParamIndex()
  1246. {
  1247. int Result;
  1248. if (FCopyParamCurrent.IsEmpty())
  1249. {
  1250. Result = -1;
  1251. }
  1252. else
  1253. {
  1254. Result = FCopyParamList->IndexOfName(FCopyParamCurrent);
  1255. }
  1256. return Result;
  1257. }
  1258. //---------------------------------------------------------------------------
  1259. void __fastcall TGUIConfiguration::SetCopyParamIndex(int value)
  1260. {
  1261. UnicodeString Name;
  1262. if (value < 0)
  1263. {
  1264. Name = L"";
  1265. }
  1266. else
  1267. {
  1268. Name = FCopyParamList->Names[value];
  1269. }
  1270. CopyParamCurrent = Name;
  1271. }
  1272. //---------------------------------------------------------------------------
  1273. void __fastcall TGUIConfiguration::SetCopyParamCurrent(UnicodeString value)
  1274. {
  1275. SET_CONFIG_PROPERTY(CopyParamCurrent);
  1276. }
  1277. //---------------------------------------------------------------------------
  1278. TGUICopyParamType __fastcall TGUIConfiguration::GetCurrentCopyParam()
  1279. {
  1280. return CopyParamPreset[CopyParamCurrent];
  1281. }
  1282. //---------------------------------------------------------------------------
  1283. TGUICopyParamType __fastcall TGUIConfiguration::GetCopyParamPreset(UnicodeString Name)
  1284. {
  1285. TGUICopyParamType Result = FDefaultCopyParam;
  1286. if (!Name.IsEmpty())
  1287. {
  1288. int Index = FCopyParamList->IndexOfName(Name);
  1289. DebugAssert(Index >= 0);
  1290. if (Index >= 0)
  1291. {
  1292. const TCopyParamType * Preset = FCopyParamList->CopyParams[Index];
  1293. DebugAssert(Preset != NULL);
  1294. Result.Assign(Preset); // overwrite all but GUI options
  1295. // reset all options known not to be configurable per-preset
  1296. // kind of hack
  1297. Result.ResumeSupport = FDefaultCopyParam.ResumeSupport;
  1298. Result.ResumeThreshold = FDefaultCopyParam.ResumeThreshold;
  1299. Result.LocalInvalidChars = FDefaultCopyParam.LocalInvalidChars;
  1300. }
  1301. }
  1302. return Result;
  1303. }
  1304. //---------------------------------------------------------------------------
  1305. bool __fastcall TGUIConfiguration::GetHasCopyParamPreset(UnicodeString Name)
  1306. {
  1307. return Name.IsEmpty() || (FCopyParamList->IndexOfName(Name) >= 0);
  1308. }
  1309. //---------------------------------------------------------------------------
  1310. void __fastcall TGUIConfiguration::SetNewDirectoryProperties(
  1311. const TRemoteProperties & value)
  1312. {
  1313. SET_CONFIG_PROPERTY(NewDirectoryProperties);
  1314. }
  1315. //---------------------------------------------------------------------------
  1316. void __fastcall TGUIConfiguration::SetQueueBootstrap(bool value)
  1317. {
  1318. SET_CONFIG_PROPERTY(QueueBootstrap);
  1319. }
  1320. //---------------------------------------------------------------------------
  1321. void __fastcall TGUIConfiguration::SetQueueKeepDoneItems(bool value)
  1322. {
  1323. SET_CONFIG_PROPERTY(QueueKeepDoneItems);
  1324. }
  1325. //---------------------------------------------------------------------------
  1326. void __fastcall TGUIConfiguration::SetQueueKeepDoneItemsFor(int value)
  1327. {
  1328. SET_CONFIG_PROPERTY(QueueKeepDoneItemsFor);
  1329. }
  1330. //---------------------------------------------------------------------
  1331. TStoredSessionList * __fastcall TGUIConfiguration::SelectPuttySessionsForImport(
  1332. const UnicodeString & RootKey, const UnicodeString & Source, TStoredSessionList * Sessions, UnicodeString & Error)
  1333. {
  1334. std::unique_ptr<TStoredSessionList> ImportSessionList(new TStoredSessionList(true));
  1335. ImportSessionList->DefaultSettings = Sessions->DefaultSettings;
  1336. UnicodeString SessionsKey = GetPuttySessionsKey(RootKey);
  1337. std::unique_ptr<TRegistryStorage> Storage(new TRegistryStorage(SessionsKey));
  1338. Storage->ConfigureForPutty();
  1339. if (Storage->OpenRootKey(false))
  1340. {
  1341. ImportSessionList->Load(Storage.get(), false, true, true);
  1342. }
  1343. TSessionData * PuttySessionData =
  1344. (TSessionData *)ImportSessionList->FindByName(PuttySession);
  1345. if (PuttySessionData != NULL)
  1346. {
  1347. ImportSessionList->Remove(PuttySessionData);
  1348. }
  1349. UnicodeString NoSessionsError = FMTLOAD(PUTTY_NO_SITES2, (Source, SessionsKey));
  1350. SelectSessionsToImportIfAny(ImportSessionList.get(), Sessions, Error, NoSessionsError);
  1351. return ImportSessionList.release();
  1352. }
  1353. //---------------------------------------------------------------------
  1354. bool __fastcall TGUIConfiguration::AnyPuttySessionForImport(TStoredSessionList * Sessions)
  1355. {
  1356. try
  1357. {
  1358. UnicodeString Error;
  1359. std::unique_ptr<TStoredSessionList> SessionsForImport(
  1360. SelectPuttySessionsForImport(OriginalPuttyRegistryStorageKey, L"PuTTY", Sessions, Error));
  1361. return (SessionsForImport->Count > 0);
  1362. }
  1363. catch (...)
  1364. {
  1365. return false;
  1366. }
  1367. }
  1368. //---------------------------------------------------------------------------