GUIConfiguration.cpp 47 KB

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