GUIConfiguration.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "GUIConfiguration.h"
  5. #include "GUITools.h"
  6. #include <Common.h>
  7. #include <FileInfo.h>
  8. #include <TextsCore.h>
  9. #include <Terminal.h>
  10. //---------------------------------------------------------------------------
  11. #pragma package(smart_init)
  12. //---------------------------------------------------------------------------
  13. // C++B TLibModule is invalid (differs from PAS definition)
  14. struct TPasLibModule {
  15. TPasLibModule * Next;
  16. void * Instance;
  17. void * CodeInstance;
  18. void * DataInstance;
  19. void * ResInstance;
  20. };
  21. //---------------------------------------------------------------------------
  22. static const unsigned int AdditionaLanguageMask = 0xFFFFFF00;
  23. static const AnsiString AdditionaLanguagePrefix("XX");
  24. //---------------------------------------------------------------------------
  25. //---------------------------------------------------------------------------
  26. __fastcall TGUICopyParamType::TGUICopyParamType()
  27. : TCopyParamType()
  28. {
  29. GUIDefault();
  30. }
  31. //---------------------------------------------------------------------------
  32. __fastcall TGUICopyParamType::TGUICopyParamType(const TCopyParamType & Source)
  33. : TCopyParamType(Source)
  34. {
  35. GUIDefault();
  36. }
  37. //---------------------------------------------------------------------------
  38. __fastcall TGUICopyParamType::TGUICopyParamType(const TGUICopyParamType & Source)
  39. : TCopyParamType(Source)
  40. {
  41. GUIAssign(&Source);
  42. }
  43. //---------------------------------------------------------------------------
  44. void __fastcall TGUICopyParamType::Assign(const TCopyParamType * Source)
  45. {
  46. TCopyParamType::Assign(Source);
  47. const TGUICopyParamType * GUISource;
  48. GUISource = dynamic_cast<const TGUICopyParamType *>(Source);
  49. if (GUISource != NULL)
  50. {
  51. GUIAssign(GUISource);
  52. }
  53. }
  54. //---------------------------------------------------------------------------
  55. void __fastcall TGUICopyParamType::GUIAssign(const TGUICopyParamType * Source)
  56. {
  57. Queue = Source->Queue;
  58. QueueNoConfirmation = Source->QueueNoConfirmation;
  59. }
  60. //---------------------------------------------------------------------------
  61. void __fastcall TGUICopyParamType::Default()
  62. {
  63. TCopyParamType::Default();
  64. GUIDefault();
  65. }
  66. //---------------------------------------------------------------------------
  67. void __fastcall TGUICopyParamType::GUIDefault()
  68. {
  69. Queue = false;
  70. QueueNoConfirmation = true;
  71. }
  72. //---------------------------------------------------------------------------
  73. TGUICopyParamType & __fastcall TGUICopyParamType::operator =(const TCopyParamType & rhp)
  74. {
  75. Assign(&rhp);
  76. return *this;
  77. }
  78. //---------------------------------------------------------------------------
  79. TGUICopyParamType & __fastcall TGUICopyParamType::operator =(const TGUICopyParamType & rhp)
  80. {
  81. Assign(&rhp);
  82. return *this;
  83. }
  84. //---------------------------------------------------------------------------
  85. //---------------------------------------------------------------------------
  86. __fastcall TGUIConfiguration::TGUIConfiguration(): TConfiguration()
  87. {
  88. FLocale = 0;
  89. FLocales = new TStringList();
  90. FLastLocalesExts = "*";
  91. dynamic_cast<TStringList*>(FLocales)->Sorted = true;
  92. dynamic_cast<TStringList*>(FLocales)->CaseSensitive = false;
  93. }
  94. //---------------------------------------------------------------------------
  95. __fastcall TGUIConfiguration::~TGUIConfiguration()
  96. {
  97. delete FLocales;
  98. }
  99. //---------------------------------------------------------------------------
  100. void __fastcall TGUIConfiguration::Default()
  101. {
  102. TConfiguration::Default();
  103. FCopyParam.Default();
  104. FIgnoreCancelBeforeFinish = TDateTime(0, 0, 3, 0);
  105. FCopyParamDialogExpanded = false;
  106. FErrorDialogExpanded = false;
  107. FContinueOnError = false;
  108. FSynchronizeParams = TTerminal::spDelete | TTerminal::spNoConfirmation;
  109. FQueueTransfersLimit = 2;
  110. FQueueAutoPopup = true;
  111. AnsiString ProgramsFolder;
  112. SpecialFolderLocation(CSIDL_PROGRAM_FILES, ProgramsFolder);
  113. FPuttyPath = IncludeTrailingBackslash(ProgramsFolder) + "PuTTY\\putty.exe";
  114. FPuttySession = "WinSCP temporary session";
  115. }
  116. //---------------------------------------------------------------------------
  117. // duplicated from core\configuration.cpp
  118. #define LASTELEM(ELEM) \
  119. ELEM.SubString(ELEM.LastDelimiter(".>")+1, ELEM.Length() - ELEM.LastDelimiter(".>"))
  120. #define BLOCK(KEY, CANCREATE, BLOCK) \
  121. if (Storage->OpenSubKey(KEY, CANCREATE)) try { BLOCK } __finally { Storage->CloseSubKey(); }
  122. #define REGCONFIG(CANCREATE) \
  123. BLOCK("Interface", CANCREATE, \
  124. KEY(Bool, CopyParamDialogExpanded); \
  125. KEY(Bool, ErrorDialogExpanded); \
  126. KEY(Bool, ContinueOnError); \
  127. KEY(Integer, SynchronizeParams); \
  128. KEY(Integer, QueueTransfersLimit); \
  129. KEY(Bool, QueueAutoPopup); \
  130. KEY(String, PuttySession); \
  131. KEY(String, PuttyPath); \
  132. KEY(DateTime, IgnoreCancelBeforeFinish); \
  133. ); \
  134. BLOCK("Interface\\CopyParam", CANCREATE, \
  135. KEY(Bool, CopyParam.AddXToDirectories); \
  136. KEY(String, CopyParam.AsciiFileMask.Masks); \
  137. KEY(Integer, CopyParam.FileNameCase); \
  138. KEY(Bool, CopyParam.PreserveReadOnly); \
  139. KEY(Bool, CopyParam.PreserveTime); \
  140. KEY(Bool, CopyParam.PreserveRights); \
  141. KEY(String, CopyParam.Rights.Text); \
  142. KEY(Integer, CopyParam.TransferMode); \
  143. KEY(Integer, CopyParam.ResumeSupport); \
  144. KEY(Int64, CopyParam.ResumeThreshold); \
  145. KEY(Bool, CopyParam.ReplaceInvalidChars); \
  146. KEY(String, CopyParam.LocalInvalidChars); \
  147. KEY(Bool, CopyParam.CalculateSize); \
  148. KEY(Bool, CopyParam.Queue); \
  149. KEY(Bool, CopyParam.QueueNoConfirmation); \
  150. ); \
  151. //---------------------------------------------------------------------------
  152. void __fastcall TGUIConfiguration::SaveSpecial(THierarchicalStorage * Storage)
  153. {
  154. TConfiguration::SaveSpecial(Storage);
  155. // duplicated from core\configuration.cpp
  156. #define KEY(TYPE, VAR) Storage->Write ## TYPE(LASTELEM(AnsiString(#VAR)), VAR)
  157. REGCONFIG(true);
  158. #undef KEY
  159. }
  160. //---------------------------------------------------------------------------
  161. void __fastcall TGUIConfiguration::LoadSpecial(THierarchicalStorage * Storage)
  162. {
  163. TConfiguration::LoadSpecial(Storage);
  164. // duplicated from core\configuration.cpp
  165. #define KEY(TYPE, VAR) VAR = Storage->Read ## TYPE(LASTELEM(AnsiString(#VAR)), VAR)
  166. #pragma warn -eas
  167. REGCONFIG(false);
  168. #pragma warn +eas
  169. #undef KEY
  170. }
  171. //---------------------------------------------------------------------------
  172. //---------------------------------------------------------------------------
  173. TPasLibModule * __fastcall TGUIConfiguration::FindModule(void * Instance)
  174. {
  175. TPasLibModule * CurModule;
  176. CurModule = reinterpret_cast<TPasLibModule*>(LibModuleList);
  177. while (CurModule)
  178. {
  179. if (CurModule->Instance == Instance)
  180. {
  181. break;
  182. }
  183. else
  184. {
  185. CurModule = CurModule->Next;
  186. }
  187. }
  188. return CurModule;
  189. }
  190. //---------------------------------------------------------------------------
  191. HANDLE __fastcall TGUIConfiguration::LoadNewResourceModule(LCID ALocale,
  192. AnsiString * FileName)
  193. {
  194. AnsiString LibraryFileName;
  195. HANDLE NewInstance = 0;
  196. bool Internal = (ALocale == InternalLocale());
  197. if (!Internal)
  198. {
  199. AnsiString Module;
  200. AnsiString LocaleName;
  201. Module = ModuleFileName();
  202. if ((ALocale & AdditionaLanguageMask) != AdditionaLanguageMask)
  203. {
  204. char LocaleStr[4];
  205. GetLocaleInfo(ALocale, LOCALE_SABBREVLANGNAME, LocaleStr, sizeof(LocaleStr));
  206. LocaleName = LocaleStr;
  207. assert(!LocaleName.IsEmpty());
  208. }
  209. else
  210. {
  211. LocaleName = AdditionaLanguagePrefix +
  212. char(ALocale & ~AdditionaLanguageMask);
  213. }
  214. Module = ChangeFileExt(Module, AnsiString(".") + LocaleName);
  215. // Look for a potential language/country translation
  216. NewInstance = LoadLibraryEx(Module.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE);
  217. if (!NewInstance)
  218. {
  219. // Finally look for a language only translation
  220. Module.SetLength(Module.Length() - 1);
  221. NewInstance = LoadLibraryEx(Module.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE);
  222. if (NewInstance)
  223. {
  224. LibraryFileName = Module;
  225. }
  226. }
  227. else
  228. {
  229. LibraryFileName = Module;
  230. }
  231. }
  232. if (!NewInstance && !Internal)
  233. {
  234. throw Exception(FMTLOAD(LOCALE_LOAD_ERROR, (int(ALocale))));
  235. }
  236. else
  237. {
  238. if (Internal)
  239. {
  240. TPasLibModule * MainModule = FindModule(HInstance);
  241. NewInstance = MainModule->Instance;
  242. }
  243. }
  244. if (FileName != NULL)
  245. {
  246. *FileName = LibraryFileName;
  247. }
  248. return NewInstance;
  249. }
  250. //---------------------------------------------------------------------------
  251. LCID __fastcall TGUIConfiguration::InternalLocale()
  252. {
  253. LCID Result;
  254. if (GetTranslationCount(ApplicationInfo) > 0)
  255. {
  256. TTranslation Translation;
  257. Translation = GetTranslation(ApplicationInfo, 0);
  258. Result = MAKELANGID(PRIMARYLANGID(Translation.Language), SUBLANG_DEFAULT);
  259. }
  260. else
  261. {
  262. assert(false);
  263. Result = 0;
  264. }
  265. return Result;
  266. }
  267. //---------------------------------------------------------------------------
  268. LCID __fastcall TGUIConfiguration::GetLocale()
  269. {
  270. if (!FLocale)
  271. {
  272. FLocale = InternalLocale();
  273. }
  274. return FLocale;
  275. }
  276. //---------------------------------------------------------------------------
  277. void __fastcall TGUIConfiguration::SetLocale(LCID value)
  278. {
  279. if (Locale != value)
  280. {
  281. HANDLE Module = LoadNewResourceModule(value);
  282. if (Module != NULL)
  283. {
  284. FLocale = value;
  285. SetResourceModule(Module);
  286. }
  287. else
  288. {
  289. assert(false);
  290. }
  291. }
  292. }
  293. //---------------------------------------------------------------------------
  294. void __fastcall TGUIConfiguration::SetLocaleSafe(LCID value)
  295. {
  296. if (Locale != value)
  297. {
  298. HANDLE Module;
  299. try
  300. {
  301. Module = LoadNewResourceModule(value);
  302. }
  303. catch(...)
  304. {
  305. // ignore any exception while loading locale
  306. Module = NULL;
  307. }
  308. if (Module != NULL)
  309. {
  310. FLocale = value;
  311. SetResourceModule(Module);
  312. }
  313. }
  314. }
  315. //---------------------------------------------------------------------------
  316. void __fastcall TGUIConfiguration::FreeResourceModule(HANDLE Instance)
  317. {
  318. TPasLibModule * MainModule = FindModule(HInstance);
  319. if (Instance != MainModule->Instance)
  320. {
  321. FreeLibrary(Instance);
  322. }
  323. }
  324. //---------------------------------------------------------------------------
  325. void __fastcall TGUIConfiguration::SetResourceModule(HANDLE Instance)
  326. {
  327. TPasLibModule * MainModule = FindModule(HInstance);
  328. FreeResourceModule(MainModule->ResInstance);
  329. MainModule->ResInstance = Instance;
  330. }
  331. //---------------------------------------------------------------------------
  332. TStrings * __fastcall TGUIConfiguration::GetLocales()
  333. {
  334. AnsiString LocalesExts;
  335. TStringList * Exts = new TStringList();
  336. try
  337. {
  338. Exts->Sorted = true;
  339. Exts->CaseSensitive = false;
  340. int FindAttrs = faReadOnly | faArchive;
  341. TSearchRec SearchRec;
  342. bool Found;
  343. Found = (bool)(FindFirst(ChangeFileExt(ModuleFileName(), ".*"),
  344. FindAttrs, SearchRec) == 0);
  345. try
  346. {
  347. AnsiString Ext;
  348. while (Found)
  349. {
  350. Ext = ExtractFileExt(SearchRec.Name).UpperCase();
  351. if ((Ext.Length() >= 3) && (Ext != ".EXE") &&
  352. (Ext != ".DLL") && (Ext != ".INI"))
  353. {
  354. Ext = Ext.SubString(2, Ext.Length() - 1);
  355. LocalesExts += Ext;
  356. Exts->Add(Ext);
  357. }
  358. Found = (FindNext(SearchRec) == 0);
  359. }
  360. }
  361. __finally
  362. {
  363. FindClose(SearchRec);
  364. }
  365. if (FLastLocalesExts != LocalesExts)
  366. {
  367. FLastLocalesExts = LocalesExts;
  368. FLocales->Clear();
  369. TLanguages * Langs = Languages();
  370. int Ext, Index, Count;
  371. char LocaleStr[255];
  372. LCID Locale;
  373. Count = Langs->Count;
  374. Index = -1;
  375. while (Index < Count)
  376. {
  377. if (Index >= 0)
  378. {
  379. Locale = Langs->LocaleID[Index];
  380. Ext = Exts->IndexOf(Langs->Ext[Index]);
  381. if (Ext < 0)
  382. {
  383. Ext = Exts->IndexOf(Langs->Ext[Index].SubString(1, 2));
  384. if (Ext >= 0)
  385. {
  386. Locale = MAKELANGID(PRIMARYLANGID(Locale), SUBLANG_DEFAULT);
  387. }
  388. }
  389. if (Ext >= 0)
  390. {
  391. Exts->Objects[Ext] = reinterpret_cast<TObject*>(Locale);
  392. }
  393. else
  394. {
  395. Locale = 0;
  396. }
  397. }
  398. else
  399. {
  400. Locale = InternalLocale();
  401. }
  402. if (Locale)
  403. {
  404. AnsiString Name;
  405. GetLocaleInfo(Locale, LOCALE_SENGLANGUAGE,
  406. LocaleStr, sizeof(LocaleStr));
  407. Name = LocaleStr;
  408. Name += " - ";
  409. // LOCALE_SNATIVELANGNAME
  410. GetLocaleInfo(Locale, LOCALE_SLANGUAGE,
  411. LocaleStr, sizeof(LocaleStr));
  412. Name += LocaleStr;
  413. FLocales->AddObject(Name, reinterpret_cast<TObject*>(Locale));
  414. }
  415. Index++;
  416. }
  417. for (int Index = 0; Index < Exts->Count; Index++)
  418. {
  419. if ((Exts->Objects[Index] == NULL) &&
  420. (Exts->Strings[Index].Length() == 3) &&
  421. SameText(Exts->Strings[Index].SubString(1, 2), AdditionaLanguagePrefix))
  422. {
  423. AnsiString LangName = GetFileFileInfoString("LangName",
  424. ChangeFileExt(ModuleFileName(), AnsiString(".") + Exts->Strings[Index]));
  425. if (!LangName.IsEmpty())
  426. {
  427. FLocales->AddObject(LangName, reinterpret_cast<TObject*>(
  428. AdditionaLanguageMask + Exts->Strings[Index][3]));
  429. }
  430. }
  431. }
  432. }
  433. }
  434. __finally
  435. {
  436. delete Exts;
  437. }
  438. return FLocales;
  439. }
  440. //---------------------------------------------------------------------------
  441. void __fastcall TGUIConfiguration::SetCopyParam(TGUICopyParamType value)
  442. {
  443. FCopyParam.Assign(&value);
  444. Changed();
  445. }