WinInterface.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <MoreButton.hpp>
  5. #include <Common.h>
  6. #include <Net.h>
  7. #include <SecureShell.h>
  8. #include <ScpMain.h>
  9. #include <TextsWin.h>
  10. #include <Interface.h>
  11. #include "WinInterface.h"
  12. #include "CustomWinConfiguration.h"
  13. #include "GUITools.h"
  14. #define mrCustom (mrYesToAll + 1)
  15. //---------------------------------------------------------------------------
  16. #pragma package(smart_init)
  17. //---------------------------------------------------------------------------
  18. TForm * __fastcall CreateMessageDialogEx(const AnsiString Msg, TQueryType Type,
  19. int Answers, int HelpCtx, int Params)
  20. {
  21. TMsgDlgButtons Buttons;
  22. TMsgDlgType DlgType;
  23. switch (Type) {
  24. case qtConfirmation: DlgType = mtConfirmation; break;
  25. case qtInformation: DlgType = mtInformation; break;
  26. case qtError: DlgType = mtError; break;
  27. case qtWarning: DlgType = mtWarning; break;
  28. default: assert(false);
  29. }
  30. #define ADD_BUTTON(TYPE) if (Answers & qa ## TYPE) Buttons << mb ## TYPE;
  31. ADD_BUTTON(Yes);
  32. ADD_BUTTON(No);
  33. ADD_BUTTON(OK);
  34. ADD_BUTTON(Cancel);
  35. ADD_BUTTON(Abort);
  36. ADD_BUTTON(Retry);
  37. ADD_BUTTON(Ignore);
  38. ADD_BUTTON(All);
  39. ADD_BUTTON(NoToAll);
  40. ADD_BUTTON(YesToAll);
  41. ADD_BUTTON(Help);
  42. #undef ADD_BUTTON
  43. if (Answers & qaSkip)
  44. {
  45. assert((Answers & qaIgnore) == 0);
  46. Buttons << mbIgnore;
  47. }
  48. if (Answers & qaPrev)
  49. {
  50. assert((Answers & qaYes) == 0);
  51. Buttons << mbYes;
  52. }
  53. if (Answers & qaNext)
  54. {
  55. assert((Answers & qaNo) == 0);
  56. Buttons << mbNo;
  57. }
  58. if (Answers & qaCustom)
  59. {
  60. assert((Answers & qaHelp) == 0);
  61. Buttons << mbHelp;
  62. }
  63. if (Answers & qaAppend)
  64. {
  65. assert((Answers & qaRetry) == 0);
  66. Buttons << mbRetry;
  67. }
  68. assert(!Buttons.Empty());
  69. TForm * Dialog = CreateMessageDialog(Msg, DlgType, Buttons);
  70. try
  71. {
  72. if (Answers & qaSkip)
  73. {
  74. TButton * IgnoreButton = dynamic_cast<TButton *>(Dialog->FindComponent("Ignore"));
  75. assert(IgnoreButton);
  76. IgnoreButton->Caption = LoadStr(SKIP_BUTTON);
  77. }
  78. if (Answers & qaPrev)
  79. {
  80. TButton * YesButton = dynamic_cast<TButton *>(Dialog->FindComponent("Yes"));
  81. assert(YesButton);
  82. YesButton->Caption = LoadStr(PREV_BUTTON);
  83. }
  84. if (Answers & qaNext)
  85. {
  86. TButton * NoButton = dynamic_cast<TButton *>(Dialog->FindComponent("No"));
  87. assert(NoButton);
  88. NoButton->Caption = LoadStr(NEXT_BUTTON);
  89. }
  90. if (Answers & qaAppend)
  91. {
  92. TButton * RetryButton = dynamic_cast<TButton *>(Dialog->FindComponent("Retry"));
  93. assert(RetryButton);
  94. RetryButton->Caption = LoadStr(APPEND_BUTTON);
  95. }
  96. if (Answers & qaCustom)
  97. {
  98. TButton * HelpButton = dynamic_cast<TButton *>(Dialog->FindComponent("Help"));
  99. assert(HelpButton);
  100. HelpButton->Name = "Custom";
  101. HelpButton->ModalResult = mrCustom;
  102. }
  103. // temporary fix of accelerators (&Abort vs. &All/Yes to &All)
  104. // must be removed
  105. for (int Index = 0; Index < Dialog->ComponentCount; Index++)
  106. {
  107. TButton * B = dynamic_cast<TButton *>(Dialog->Components[Index]);
  108. if (B)
  109. {
  110. if (B->Caption == "&All") B->Caption = "A&ll";
  111. else
  112. if (B->Caption == "Yes to &All") B->Caption = "Yes to A&ll";
  113. }
  114. }
  115. if (Params & mpNeverAskAgainCheck)
  116. {
  117. Dialog->ClientHeight = Dialog->ClientHeight + 20;
  118. TCheckBox * NeverAskAgainCheck = new TCheckBox(Dialog);
  119. NeverAskAgainCheck->Name = "NeverAskAgainCheck";
  120. NeverAskAgainCheck->Parent = Dialog;
  121. NeverAskAgainCheck->BoundsRect = TRect(60, Dialog->ClientHeight - 27,
  122. Dialog->ClientWidth - 10, Dialog->ClientHeight - 5);
  123. NeverAskAgainCheck->Caption = LoadStr(NEVER_ASK_AGAIN);
  124. NeverAskAgainCheck->Checked = false;
  125. }
  126. Dialog->HelpContext = HelpCtx;
  127. Dialog->Position = poMainFormCenter;
  128. }
  129. catch(...)
  130. {
  131. delete Dialog;
  132. throw;
  133. }
  134. return Dialog;
  135. }
  136. //---------------------------------------------------------------------------
  137. int __fastcall ExecuteMessageDialog(TForm * Dialog, int Answers, int Params)
  138. {
  139. int Result, Answer;
  140. FlashOnBackground();
  141. Result = Dialog->ShowModal();
  142. switch (Result) {
  143. #define MAP_RESULT(RESULT) case mr ## RESULT: Answer = qa ## RESULT; break;
  144. MAP_RESULT(Cancel);
  145. MAP_RESULT(Abort);
  146. MAP_RESULT(All);
  147. MAP_RESULT(NoToAll);
  148. MAP_RESULT(YesToAll);
  149. MAP_RESULT(Custom);
  150. #undef MAP_RESULT
  151. case mrOk:
  152. Answer = qaOK;
  153. break;
  154. case mrIgnore:
  155. Answer = (Answers & qaSkip) ? qaSkip : qaIgnore;
  156. break;
  157. case mrYes:
  158. Answer = (Answers & qaPrev) ? qaPrev : qaYes;
  159. break;
  160. case mrNo:
  161. Answer = (Answers & qaNext) ? qaNext : qaNo;
  162. break;
  163. case mrRetry:
  164. Answer = (Answers & qaAppend) ? qaAppend : qaRetry;
  165. break;
  166. }
  167. if (Params & mpNeverAskAgainCheck)
  168. {
  169. TCheckBox * NeverAskAgainCheck =
  170. dynamic_cast<TCheckBox *>(Dialog->FindComponent("NeverAskAgainCheck"));
  171. assert(NeverAskAgainCheck);
  172. if (NeverAskAgainCheck->Checked &&
  173. (Answer == qaYes || Answer == qaOK || Answer == qaYesToAll))
  174. {
  175. Answer = qaNeverAskAgain;
  176. }
  177. }
  178. TMoreButton * MoreButton = dynamic_cast<TMoreButton *>(Dialog->FindComponent("MoreButton"));
  179. // WinConfiguration may be destroyed already, if called from
  180. // try ... catch statement of main()
  181. if (MoreButton && GUIConfiguration)
  182. {
  183. // store state even when user selects 'Cancel'?
  184. GUIConfiguration->ErrorDialogExpanded = MoreButton->Expanded;
  185. }
  186. return Answer;
  187. }
  188. //---------------------------------------------------------------------------
  189. int __fastcall MessageDialog(const AnsiString Msg, TQueryType Type,
  190. int Answers, int HelpCtx, int Params)
  191. {
  192. int Result;
  193. TForm * Dialog = CreateMessageDialogEx(Msg, Type, Answers, HelpCtx, Params);
  194. try
  195. {
  196. Result = ExecuteMessageDialog(Dialog, Answers, Params);
  197. }
  198. __finally
  199. {
  200. delete Dialog;
  201. }
  202. return Result;
  203. }
  204. //---------------------------------------------------------------------------
  205. TForm * __fastcall CreateMoreMessageDialog(const AnsiString Message,
  206. TStrings * MoreMessages, TQueryType Type, int Answers,
  207. int HelpCtx, int Params)
  208. {
  209. if (!MoreMessages || (MoreMessages->Count == 0))
  210. {
  211. return CreateMessageDialogEx(Message, Type, Answers, HelpCtx, Params);
  212. }
  213. else
  214. {
  215. TForm * Dialog;
  216. Answers |= qaCustom;
  217. Dialog = CreateMessageDialogEx(Message, Type, Answers, HelpCtx, Params);
  218. try
  219. {
  220. TButton * CustomButton = dynamic_cast<TButton *>(Dialog->FindComponent("Custom"));
  221. TLabel * MsgLabel = dynamic_cast<TLabel *>(Dialog->FindComponent("Message"));
  222. assert(MsgLabel && CustomButton);
  223. int OrigButtonTop = CustomButton->Top;
  224. int WidthDelta = 0;
  225. if (Dialog->ClientWidth < 400)
  226. {
  227. WidthDelta = (400 - Dialog->ClientWidth);
  228. }
  229. Dialog->ClientHeight = Dialog->ClientHeight + 130;
  230. Dialog->ClientWidth = Dialog->ClientWidth + WidthDelta;
  231. MsgLabel->Width = MsgLabel->Width + WidthDelta;
  232. for (int Index = 0; Index < Dialog->ControlCount; Index++)
  233. {
  234. if (Dialog->Controls[Index]->InheritsFrom(__classid(TButton)))
  235. {
  236. TControl * Control = Dialog->Controls[Index];
  237. Control->Anchors = TAnchors() << akBottom << akLeft;
  238. Control->Top = Control->Top + 130;
  239. Control->Left = Control->Left + (WidthDelta / 2);
  240. }
  241. }
  242. TMemo * MessageMemo = new TMemo(Dialog);
  243. MessageMemo->Parent = Dialog;
  244. MessageMemo->ReadOnly = True;
  245. MessageMemo->WantReturns = False;
  246. MessageMemo->ScrollBars = ssVertical;
  247. MessageMemo->Anchors = TAnchors() << akLeft << akRight << akTop; //akBottom;
  248. MessageMemo->BoundsRect = TRect(MsgLabel->Left, OrigButtonTop - 10,
  249. Dialog->ClientWidth - 20, CustomButton->Top - 10);
  250. MessageMemo->Color = clBtnFace;
  251. MessageMemo->Lines->Text = MoreMessages->Text;
  252. TMoreButton * MoreButton = new TMoreButton(Dialog);
  253. MoreButton->Parent = Dialog;
  254. MoreButton->BoundsRect = CustomButton->BoundsRect;
  255. MoreButton->Anchors = CustomButton->Anchors;
  256. MoreButton->Panel = MessageMemo;
  257. // WinConfiguration may be destroyed already, if called from
  258. // try ... catch statement of main()
  259. MoreButton->Expanded = GUIConfiguration && GUIConfiguration->ErrorDialogExpanded;
  260. MoreButton->Name = "MoreButton";
  261. MessageMemo->TabOrder = 20;
  262. delete CustomButton;
  263. }
  264. catch(...)
  265. {
  266. delete Dialog;
  267. throw;
  268. }
  269. return Dialog;
  270. }
  271. }
  272. //---------------------------------------------------------------------------
  273. int __fastcall MoreMessageDialog(const AnsiString Message, TStrings * MoreMessages,
  274. TQueryType Type, int Answers, int HelpCtx, int Params)
  275. {
  276. int Result;
  277. TForm * Dialog;
  278. Dialog = CreateMoreMessageDialog(Message, MoreMessages, Type,
  279. Answers, HelpCtx, Params);
  280. try
  281. {
  282. Result = ExecuteMessageDialog(Dialog, Answers, Params);
  283. }
  284. __finally
  285. {
  286. delete Dialog;
  287. }
  288. return Result;
  289. }
  290. //---------------------------------------------------------------------------
  291. int __fastcall SimpleErrorDialog(const AnsiString Msg)
  292. {
  293. return MessageDialog(Msg, qtError, qaOK, 0);
  294. }
  295. //---------------------------------------------------------------------------
  296. int __fastcall ExceptionMessageDialog(Exception * E,
  297. TQueryType Type, int Answers, int HelpCtx)
  298. {
  299. TStrings * MoreMessages = NULL;
  300. if (E->InheritsFrom(__classid(ExtException)))
  301. {
  302. MoreMessages = ((ExtException *)E)->MoreMessages;
  303. }
  304. int Result;
  305. TForm * Dialog;
  306. Dialog = CreateMoreMessageDialog(E->Message, MoreMessages, Type,
  307. Answers, HelpCtx, 0);
  308. try
  309. {
  310. Result = ExecuteMessageDialog(Dialog, Answers, 0);
  311. }
  312. __finally
  313. {
  314. delete Dialog;
  315. }
  316. return Result;
  317. }
  318. //---------------------------------------------------------------------------
  319. int __fastcall FatalExceptionMessageDialog(Exception * E,
  320. TQueryType Type, AnsiString MessageFormat, int Answers, int HelpCtx, int Params)
  321. {
  322. TStrings * MoreMessages = NULL;
  323. if (E->InheritsFrom(__classid(ExtException)))
  324. {
  325. MoreMessages = ((ExtException *)E)->MoreMessages;
  326. }
  327. assert((Answers & qaRetry) == 0);
  328. Answers |= qaRetry;
  329. int Result;
  330. TForm * Dialog = CreateMoreMessageDialog(
  331. FORMAT(MessageFormat, (E->Message)), MoreMessages, Type,
  332. Answers, HelpCtx, Params);
  333. try
  334. {
  335. TButton * RetryButton = dynamic_cast<TButton *>(Dialog->FindComponent("Retry"));
  336. assert(RetryButton);
  337. RetryButton->Caption = LoadStr(RECONNECT_BUTTON);
  338. Result = ExecuteMessageDialog(Dialog, Answers, Params);
  339. }
  340. __finally
  341. {
  342. delete Dialog;
  343. }
  344. return Result;
  345. }
  346. //---------------------------------------------------------------------------
  347. int __fastcall GetSessionPassword(AnsiString Prompt,
  348. TPasswordKind Kind, AnsiString & Password)
  349. {
  350. return DoPasswordDialog(Prompt, Kind, Password);
  351. }
  352. //---------------------------------------------------------------------------
  353. void __fastcall Busy(bool Start)
  354. {
  355. static int Busy = 0;
  356. static TCursor PrevCursor;
  357. if (Start)
  358. {
  359. if (!Busy)
  360. {
  361. PrevCursor = Screen->Cursor;
  362. Screen->Cursor = crHourGlass;
  363. }
  364. Busy++;
  365. assert(Busy < 10);
  366. }
  367. else
  368. {
  369. assert(Busy > 0);
  370. Busy--;
  371. if (!Busy)
  372. {
  373. Screen->Cursor = PrevCursor;
  374. }
  375. }
  376. }
  377. //---------------------------------------------------------------------------
  378. bool __fastcall DoRemoteMoveDialog(TStrings * FileList, AnsiString & Target,
  379. AnsiString & FileMask)
  380. {
  381. AnsiString Prompt = FileNameFormatString(LoadStr(REMOTE_MOVE_FILE),
  382. LoadStr(REMOTE_MOVE_FILES), FileList, true);
  383. AnsiString Value = UnixIncludeTrailingBackslash(Target) + FileMask;
  384. TStrings * History = CustomWinConfiguration->History["RemoteTarget"];
  385. bool Result = InputDialog(LoadStr(REMOTE_MOVE_TITLE), Prompt,
  386. Value, History);
  387. if (Result)
  388. {
  389. CustomWinConfiguration->History["RemoteTarget"] = History;
  390. Target = UnixExtractFilePath(Value);
  391. FileMask = UnixExtractFileName(Value);
  392. }
  393. return Result;
  394. }