GUITools.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. //---------------------------------------------------------------------------
  2. #define NO_WIN32_LEAN_AND_MEAN
  3. #include <vcl.h>
  4. #pragma hdrstop
  5. #include <shlobj.h>
  6. #include <Common.h>
  7. #include "GUITools.h"
  8. #include "GUIConfiguration.h"
  9. #include <TextsCore.h>
  10. #include <CoreMain.h>
  11. #include <SessionData.h>
  12. //---------------------------------------------------------------------------
  13. #pragma package(smart_init)
  14. //---------------------------------------------------------------------------
  15. bool __fastcall FindFile(AnsiString & Path)
  16. {
  17. bool Result = FileExists(Path);
  18. if (!Result)
  19. {
  20. int Len = GetEnvironmentVariable("PATH", NULL, 0);
  21. if (Len > 0)
  22. {
  23. AnsiString Paths;
  24. Paths.SetLength(Len - 1);
  25. GetEnvironmentVariable("PATH", Paths.c_str(), Len);
  26. AnsiString NewPath = FileSearch(ExtractFileName(Path), Paths);
  27. Result = !NewPath.IsEmpty();
  28. if (Result)
  29. {
  30. Path = NewPath;
  31. }
  32. }
  33. }
  34. return Result;
  35. }
  36. //---------------------------------------------------------------------------
  37. bool __fastcall FileExistsEx(AnsiString Path)
  38. {
  39. return FindFile(Path);
  40. }
  41. //---------------------------------------------------------------------------
  42. void __fastcall OpenSessionInPutty(const AnsiString PuttyPath,
  43. TSessionData * SessionData, AnsiString Password)
  44. {
  45. AnsiString Program, Params, Dir;
  46. SplitCommand(PuttyPath, Program, Params, Dir);
  47. Program = ExpandEnvironmentVariables(Program);
  48. if (FindFile(Program))
  49. {
  50. AnsiString SessionName;
  51. TRegistryStorage * Storage = NULL;
  52. TSessionData * ExportData = NULL;
  53. TRegistryStorage * SourceStorage = NULL;
  54. try
  55. {
  56. Storage = new TRegistryStorage(Configuration->PuttySessionsKey);
  57. Storage->AccessMode = smReadWrite;
  58. if (Storage->OpenRootKey(true))
  59. {
  60. if (Storage->KeyExists(SessionData->StorageKey))
  61. {
  62. SessionName = SessionData->SessionName;
  63. }
  64. else
  65. {
  66. SourceStorage = new TRegistryStorage(Configuration->PuttySessionsKey);
  67. if (SourceStorage->OpenSubKey(StoredSessions->DefaultSettings->Name, false) &&
  68. Storage->OpenSubKey(GUIConfiguration->PuttySession, true))
  69. {
  70. Storage->Copy(SourceStorage);
  71. Storage->CloseSubKey();
  72. }
  73. ExportData = new TSessionData("");
  74. ExportData->Assign(SessionData);
  75. ExportData->Modified = true;
  76. ExportData->Name = GUIConfiguration->PuttySession;
  77. ExportData->Password = "";
  78. if (SessionData->FSProtocol == fsFTP)
  79. {
  80. if (GUIConfiguration->TelnetForFtpInPutty)
  81. {
  82. ExportData->Protocol = ptTelnet;
  83. ExportData->PortNumber = 23;
  84. // PuTTY does not allow -pw for telnet
  85. Password = "";
  86. }
  87. else
  88. {
  89. ExportData->Protocol = ptSSH;
  90. ExportData->PortNumber = 22;
  91. }
  92. }
  93. ExportData->Save(Storage, true);
  94. SessionName = GUIConfiguration->PuttySession;
  95. }
  96. }
  97. }
  98. __finally
  99. {
  100. delete Storage;
  101. delete ExportData;
  102. delete SourceStorage;
  103. }
  104. if (!Params.IsEmpty())
  105. {
  106. Params += " ";
  107. }
  108. if (!Password.IsEmpty())
  109. {
  110. Params += FORMAT("-pw \"%s\" ", (Password));
  111. }
  112. Params += FORMAT("-load \"%s\"", (SessionName));
  113. if (!ExecuteShell(Program, Params))
  114. {
  115. throw Exception(FMTLOAD(EXECUTE_APP_ERROR, (Program)));
  116. }
  117. }
  118. else
  119. {
  120. throw Exception(FMTLOAD(FILE_NOT_FOUND, (Program)));
  121. }
  122. }
  123. //---------------------------------------------------------------------------
  124. bool __fastcall ExecuteShell(const AnsiString Path, const AnsiString Params)
  125. {
  126. return ((int)ShellExecute(NULL, "open", (char*)Path.data(),
  127. (char*)Params.data(), NULL, SW_SHOWNORMAL) > 32);
  128. }
  129. //---------------------------------------------------------------------------
  130. bool __fastcall ExecuteShell(const AnsiString Path, const AnsiString Params,
  131. HANDLE & Handle)
  132. {
  133. bool Result;
  134. TShellExecuteInfo ExecuteInfo;
  135. memset(&ExecuteInfo, 0, sizeof(ExecuteInfo));
  136. ExecuteInfo.cbSize = sizeof(ExecuteInfo);
  137. ExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
  138. ExecuteInfo.hwnd = Application->Handle;
  139. ExecuteInfo.lpFile = (char*)Path.data();
  140. ExecuteInfo.lpParameters = (char*)Params.data();
  141. ExecuteInfo.nShow = SW_SHOW;
  142. Result = (ShellExecuteEx(&ExecuteInfo) != 0);
  143. if (Result)
  144. {
  145. Handle = ExecuteInfo.hProcess;
  146. }
  147. return Result;
  148. }
  149. //---------------------------------------------------------------------------
  150. bool __fastcall ExecuteShellAndWait(HWND Handle, const AnsiString Path,
  151. const AnsiString Params, TProcessMessagesEvent ProcessMessages)
  152. {
  153. bool Result;
  154. TShellExecuteInfo ExecuteInfo;
  155. memset(&ExecuteInfo, 0, sizeof(ExecuteInfo));
  156. ExecuteInfo.cbSize = sizeof(ExecuteInfo);
  157. ExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
  158. ExecuteInfo.hwnd = Handle;
  159. ExecuteInfo.lpFile = (char*)Path.data();
  160. ExecuteInfo.lpParameters = (char*)Params.data();
  161. ExecuteInfo.nShow = SW_SHOW;
  162. Result = (ShellExecuteEx(&ExecuteInfo) != 0);
  163. if (Result)
  164. {
  165. if (ProcessMessages != NULL)
  166. {
  167. unsigned long WaitResult;
  168. do
  169. {
  170. WaitResult = WaitForSingleObject(ExecuteInfo.hProcess, 200);
  171. if (WaitResult == WAIT_FAILED)
  172. {
  173. throw Exception(LoadStr(DOCUMENT_WAIT_ERROR));
  174. }
  175. ProcessMessages();
  176. }
  177. while (WaitResult == WAIT_TIMEOUT);
  178. }
  179. else
  180. {
  181. WaitForSingleObject(ExecuteInfo.hProcess, INFINITE);
  182. }
  183. }
  184. return Result;
  185. }
  186. //---------------------------------------------------------------------------
  187. bool __fastcall ExecuteShellAndWait(HWND Handle, const AnsiString Command,
  188. TProcessMessagesEvent ProcessMessages)
  189. {
  190. AnsiString Program, Params, Dir;
  191. SplitCommand(Command, Program, Params, Dir);
  192. return ExecuteShellAndWait(Handle, Program, Params, ProcessMessages);
  193. }
  194. //---------------------------------------------------------------------------
  195. bool __fastcall SpecialFolderLocation(int PathID, AnsiString & Path)
  196. {
  197. LPITEMIDLIST Pidl;
  198. char Buf[256];
  199. if (SHGetSpecialFolderLocation(NULL, PathID, &Pidl) == NO_ERROR &&
  200. SHGetPathFromIDList(Pidl, Buf))
  201. {
  202. Path = AnsiString(Buf);
  203. return true;
  204. }
  205. return false;
  206. }
  207. //---------------------------------------------------------------------------
  208. AnsiString __fastcall ItemsFormatString(const AnsiString SingleItemFormat,
  209. const AnsiString MultiItemsFormat, int Count, const AnsiString FirstItem)
  210. {
  211. AnsiString Result;
  212. if (Count == 1)
  213. {
  214. Result = FORMAT(SingleItemFormat, (FirstItem));
  215. }
  216. else
  217. {
  218. Result = FORMAT(MultiItemsFormat, (Count));
  219. }
  220. return Result;
  221. }
  222. //---------------------------------------------------------------------------
  223. AnsiString __fastcall ItemsFormatString(const AnsiString SingleItemFormat,
  224. const AnsiString MultiItemsFormat, TStrings * Items)
  225. {
  226. return ItemsFormatString(SingleItemFormat, MultiItemsFormat,
  227. Items->Count, (Items->Count > 0 ? Items->Strings[0] : AnsiString()));
  228. }
  229. //---------------------------------------------------------------------------
  230. AnsiString __fastcall FileNameFormatString(const AnsiString SingleFileFormat,
  231. const AnsiString MultiFilesFormat, TStrings * Files, bool Remote)
  232. {
  233. assert(Files != NULL);
  234. AnsiString Item;
  235. if (Files->Count > 0)
  236. {
  237. Item = Remote ? UnixExtractFileName(Files->Strings[0]) :
  238. ExtractFileName(Files->Strings[0]);
  239. }
  240. return ItemsFormatString(SingleFileFormat, MultiFilesFormat,
  241. Files->Count, Item);
  242. }
  243. //---------------------------------------------------------------------
  244. AnsiString __fastcall FormatBytes(__int64 Bytes, bool UseOrders)
  245. {
  246. AnsiString Result;
  247. if (!UseOrders || (Bytes < __int64(100*1024)))
  248. {
  249. Result = FormatFloat("#,##0 \"B\"", Bytes);
  250. }
  251. else if (Bytes < __int64(100*1024*1024))
  252. {
  253. Result = FormatFloat("#,##0 \"KiB\"", Bytes / 1024);
  254. }
  255. else
  256. {
  257. Result = FormatFloat("#,##0 \"MiB\"", Bytes / (1024*1024));
  258. }
  259. return Result;
  260. }
  261. //---------------------------------------------------------------------------
  262. AnsiString __fastcall UniqTempDir(const AnsiString BaseDir, const AnsiString Identity,
  263. bool Mask)
  264. {
  265. AnsiString TempDir;
  266. do
  267. {
  268. TempDir = BaseDir.IsEmpty() ? SystemTemporaryDirectory() : BaseDir;
  269. TempDir = IncludeTrailingBackslash(TempDir) + Identity;
  270. if (Mask)
  271. {
  272. TempDir += "?????";
  273. }
  274. else
  275. {
  276. TempDir += IncludeTrailingBackslash(FormatDateTime("nnzzz", Now()));
  277. };
  278. }
  279. while (!Mask && DirectoryExists(TempDir));
  280. return TempDir;
  281. }
  282. //---------------------------------------------------------------------------
  283. bool __fastcall DeleteDirectory(const AnsiString DirName)
  284. {
  285. TSearchRec sr;
  286. bool retval = true;
  287. if (FindFirst(DirName + "\\*", faAnyFile, sr) == 0) // VCL Function
  288. {
  289. if (FLAGSET(sr.Attr, faDirectory))
  290. {
  291. if (sr.Name != "." && sr.Name != "..")
  292. retval = DeleteDirectory(DirName + "\\" + sr.Name);
  293. }
  294. else
  295. {
  296. retval = DeleteFile(DirName + "\\" + sr.Name);
  297. }
  298. if (retval)
  299. {
  300. while (FindNext(sr) == 0)
  301. { // VCL Function
  302. if (FLAGSET(sr.Attr, faDirectory))
  303. {
  304. if (sr.Name != "." && sr.Name != "..")
  305. retval = DeleteDirectory(DirName + "\\" + sr.Name);
  306. }
  307. else
  308. {
  309. retval = DeleteFile(DirName + "\\" + sr.Name);
  310. }
  311. if (!retval) break;
  312. }
  313. }
  314. }
  315. FindClose(sr);
  316. if (retval) retval = RemoveDir(DirName); // VCL function
  317. return retval;
  318. }
  319. //---------------------------------------------------------------------------
  320. AnsiString __fastcall TranslateExceptionMessage(const Exception * E)
  321. {
  322. if (dynamic_cast<const EAccessViolation*>(E) != NULL)
  323. {
  324. return LoadStr(ACCESS_VIOLATION_ERROR);
  325. }
  326. else
  327. {
  328. return E->Message;
  329. }
  330. }
  331. //---------------------------------------------------------------------------
  332. AnsiString __fastcall FormatDateTimeSpan(const AnsiString TimeFormat, TDateTime DateTime)
  333. {
  334. AnsiString Result;
  335. if (int(DateTime) > 0)
  336. {
  337. Result = IntToStr(int(DateTime)) + ", ";
  338. }
  339. // days are decremented, because when there are to many of them,
  340. // "integer overflow" error occurs
  341. Result += FormatDateTime(TimeFormat, DateTime - int(DateTime));
  342. return Result;
  343. }
  344. //---------------------------------------------------------------------------
  345. TLocalCustomCommand::TLocalCustomCommand()
  346. {
  347. }
  348. //---------------------------------------------------------------------------
  349. TLocalCustomCommand::TLocalCustomCommand(const TCustomCommandData & Data,
  350. const AnsiString & Path) :
  351. TFileCustomCommand(Data, Path)
  352. {
  353. }
  354. //---------------------------------------------------------------------------
  355. TLocalCustomCommand::TLocalCustomCommand(const TCustomCommandData & Data,
  356. const AnsiString & Path, const AnsiString & FileName,
  357. const AnsiString & LocalFileName, const AnsiString & FileList) :
  358. TFileCustomCommand(Data, Path, FileName, FileList)
  359. {
  360. FLocalFileName = LocalFileName;
  361. }
  362. //---------------------------------------------------------------------------
  363. int __fastcall TLocalCustomCommand::PatternLen(int Index, char PatternCmd)
  364. {
  365. int Len;
  366. if (PatternCmd == '^')
  367. {
  368. Len = 3;
  369. }
  370. else
  371. {
  372. Len = TFileCustomCommand::PatternLen(Index, PatternCmd);
  373. }
  374. return Len;
  375. }
  376. //---------------------------------------------------------------------------
  377. bool __fastcall TLocalCustomCommand::PatternReplacement(int Index,
  378. const AnsiString & Pattern, AnsiString & Replacement, bool & Delimit)
  379. {
  380. bool Result;
  381. if (Pattern == "!^!")
  382. {
  383. Replacement = FLocalFileName;
  384. Result = true;
  385. }
  386. else
  387. {
  388. Result = TFileCustomCommand::PatternReplacement(Index, Pattern, Replacement, Delimit);
  389. }
  390. return Result;
  391. }
  392. //---------------------------------------------------------------------------
  393. void __fastcall TLocalCustomCommand::DelimitReplacement(
  394. AnsiString & /*Replacement*/, char /*Quote*/)
  395. {
  396. // never delimit local commands
  397. }
  398. //---------------------------------------------------------------------------
  399. bool __fastcall TLocalCustomCommand::HasLocalFileName(const AnsiString & Command)
  400. {
  401. return FindPattern(Command, '^');
  402. }
  403. //---------------------------------------------------------------------------
  404. bool __fastcall TLocalCustomCommand::IsFileCommand(const AnsiString & Command)
  405. {
  406. return TFileCustomCommand::IsFileCommand(Command) || HasLocalFileName(Command);
  407. }