/platform/platform-impl/src/com/intellij/ui/mac/MacMessagesImpl.java

https://bitbucket.org/nbargnesi/idea · Java · 556 lines · 414 code · 95 blank · 47 comment · 104 complexity · cbb8e7e7f7f3ad4de6968bceef6d616e MD5 · raw file

  1. /*
  2. * Copyright 2000-2011 JetBrains s.r.o.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.intellij.ui.mac;
  17. import com.intellij.openapi.diagnostic.Logger;
  18. import com.intellij.openapi.ui.DialogWrapper;
  19. import com.intellij.openapi.util.Pair;
  20. import com.intellij.openapi.util.SystemInfo;
  21. import com.intellij.openapi.util.text.StringUtil;
  22. import com.intellij.openapi.wm.IdeFocusManager;
  23. import com.intellij.openapi.wm.IdeFrame;
  24. import com.intellij.openapi.wm.WindowManager;
  25. import com.intellij.ui.FocusTrackback;
  26. import com.intellij.ui.mac.foundation.Foundation;
  27. import com.intellij.ui.mac.foundation.ID;
  28. import com.intellij.ui.mac.foundation.MacUtil;
  29. import com.intellij.util.PairFunction;
  30. import com.intellij.util.ui.UIUtil;
  31. import com.sun.jna.Callback;
  32. import org.jetbrains.annotations.Nullable;
  33. import javax.swing.*;
  34. import java.awt.*;
  35. import static com.intellij.ui.mac.foundation.Foundation.*;
  36. /**
  37. * @author pegov
  38. */
  39. public class MacMessagesImpl extends MacMessages {
  40. private static final Logger LOG = Logger.getInstance("#com.intellij.ui.mac.MacMessages");
  41. private static final Callback SHEET_DID_END = new Callback() {
  42. public void callback(ID self, String selector, ID alert, ID returnCode, ID contextInfo) {
  43. String fakeDialogTitle = toStringViaUTF8(contextInfo);
  44. Window[] windows = Window.getWindows();
  45. ID suppressState = invoke(invoke(alert, "suppressionButton"), "state");
  46. for (Window window : windows) {
  47. if (window instanceof JFrame) {
  48. JFrame frame = (JFrame)window;
  49. JRootPane rootPane = frame.getRootPane();
  50. if (rootPane.getClientProperty(MacUtil.MAC_NATIVE_WINDOW_SHOWING) == Boolean.TRUE &&
  51. fakeDialogTitle.equals(rootPane.getClientProperty(MAC_SHEET_ID))) {
  52. processResult(rootPane, returnCode.intValue(), suppressState.intValue());
  53. break;
  54. }
  55. }
  56. else if (window instanceof JDialog) {
  57. JDialog dialog = (JDialog)window;
  58. JRootPane rootPane = dialog.getRootPane();
  59. if (rootPane.getClientProperty(MacUtil.MAC_NATIVE_WINDOW_SHOWING) == Boolean.TRUE &&
  60. fakeDialogTitle.equals(rootPane.getClientProperty(MAC_SHEET_ID))) {
  61. processResult(rootPane, returnCode.intValue(), suppressState.intValue());
  62. }
  63. }
  64. }
  65. cfRelease(self);
  66. }
  67. };
  68. private static final Callback VARIABLE_BUTTONS_SHEET_PANEL = new Callback() {
  69. public void callback(ID self, String selector, ID params) {
  70. ID title = invoke(params, "objectAtIndex:", 0);
  71. ID message = invoke(params, "objectAtIndex:", 1);
  72. ID focusedWindow = invoke(params, "objectAtIndex:", 2);
  73. ID fakeId = invoke(params, "objectAtIndex:", 3);
  74. ID alertStyle = invoke(params, "objectAtIndex:", 4);
  75. ID doNotAskText = invoke(params, "objectAtIndex:", 5);
  76. int defaultOptionIndex = Integer.parseInt(toStringViaUTF8(invoke(params, "objectAtIndex:", 6)));
  77. int focusedOptionIndex = Integer.parseInt(toStringViaUTF8(invoke(params, "objectAtIndex:", 7)));
  78. ID buttons = invoke(params, "objectAtIndex:", 8);
  79. ID doNotAskChecked = invoke(params, "objectAtIndex:", 9);
  80. ID alert = invoke(invoke("NSAlert", "alloc"), "init");
  81. invoke(alert, "setMessageText:", title);
  82. invoke(alert, "setInformativeText:", message);
  83. if ("error".equals(toStringViaUTF8(alertStyle))) {
  84. invoke(alert, "setAlertStyle:", 2); // NSCriticalAlertStyle = 2
  85. }
  86. final ID buttonEnumerator = invoke(buttons, "objectEnumerator");
  87. while (true) {
  88. final ID button = invoke(buttonEnumerator, "nextObject");
  89. if (0 == button.intValue()) break;
  90. invoke(alert, "addButtonWithTitle:", button);
  91. }
  92. if (defaultOptionIndex != -1) {
  93. invoke(invoke(alert, "window"), "setDefaultButtonCell:",
  94. invoke(invoke(invoke(alert, "buttons"), "objectAtIndex:", defaultOptionIndex), "cell"));
  95. }
  96. // it seems like asking for focus will cause java to go and query focus owner too, which may cause dead locks on main-thread
  97. //if (focusedOptionIndex != -1) {
  98. // invoke(invoke(alert, "window"), "makeFirstResponder:",
  99. // invoke(invoke(alert, "buttons"), "objectAtIndex:", focusedOptionIndex));
  100. //} else {
  101. // int count = invoke(buttons, "count").intValue();
  102. // invoke(invoke(alert, "window"), "makeFirstResponder:",
  103. // invoke(invoke(alert, "buttons"), "objectAtIndex:", count == 1 ? 0 : 1));
  104. //}
  105. String doNotAsk = toStringViaUTF8(doNotAskText);
  106. if (!"-1".equals(doNotAsk)) {
  107. invoke(alert, "setShowsSuppressionButton:", 1);
  108. invoke(invoke(alert, "suppressionButton"), "setTitle:", doNotAskText);
  109. invoke(invoke(alert, "suppressionButton"), "setState:", "checked".equals(toStringViaUTF8(doNotAskChecked)));
  110. }
  111. invoke(alert, "beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:", focusedWindow, self,
  112. createSelector("alertDidEnd:returnCode:contextInfo:"), fakeId);
  113. }
  114. };
  115. private static final Callback SIMPLE_SHEET_PANEL = new Callback() {
  116. public void callback(ID self, String selector, ID params) {
  117. ID title = invoke(params, "objectAtIndex:", 0);
  118. ID defaultText = invoke(params, "objectAtIndex:", 1);
  119. ID otherText = invoke(params, "objectAtIndex:", 2);
  120. ID alternateText = invoke(params, "objectAtIndex:", 3);
  121. ID message = invoke(params, "objectAtIndex:", 4);
  122. ID focusedWindow = invoke(params, "objectAtIndex:", 5);
  123. ID fakeId = invoke(params, "objectAtIndex:", 6);
  124. ID alertStyle = invoke(params, "objectAtIndex:", 7);
  125. ID doNotAskText = invoke(params, "objectAtIndex:", 8);
  126. ID doNotAskChecked = invoke(params, "objectAtIndex:", 9);
  127. boolean alternateExist = !"-1".equals(toStringViaUTF8(alternateText));
  128. boolean otherExist = !"-1".equals(toStringViaUTF8(otherText));
  129. final ID alert = invoke("NSAlert", "alertWithMessageText:defaultButton:alternateButton:otherButton:informativeTextWithFormat:",
  130. title, defaultText, alternateExist ? alternateText : null, otherExist ? otherText : null, message);
  131. if ("error".equals(toStringViaUTF8(alertStyle))) {
  132. invoke(alert, "setAlertStyle:", 2); // NSCriticalAlertStyle = 2
  133. }
  134. // it seems like asking for focus will cause java to go and query focus owner too, which may cause dead locks on main-thread
  135. //ID window = invoke(alert, "window");
  136. //invoke(window, "makeFirstResponder:",
  137. // invoke(invoke(alert, "buttons"), "objectAtIndex:", alternateExist ? 2 : otherExist ? 1 : 0));
  138. // it is impossible to override ESCAPE key behavior -> key should be named "Cancel" to be bound to ESC
  139. //if (!alternateExist) {
  140. //invoke(invoke(invoke(alert, "buttons"), "objectAtIndex:", 1), "setKeyEquivalent:", nsString("\\e"));
  141. //}
  142. String doNotAsk = toStringViaUTF8(doNotAskText);
  143. if (!"-1".equals(doNotAsk)) {
  144. invoke(alert, "setShowsSuppressionButton:", 1);
  145. invoke(invoke(alert, "suppressionButton"), "setTitle:", doNotAskText);
  146. invoke(invoke(alert, "suppressionButton"), "setState:", "checked".equals(toStringViaUTF8(doNotAskChecked)));
  147. }
  148. invoke(alert, "beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:", focusedWindow, self,
  149. createSelector("alertDidEnd:returnCode:contextInfo:"), fakeId);
  150. }
  151. };
  152. private static void processResult(JRootPane rootPane, int returnCode, int suppressDialog) {
  153. rootPane.putClientProperty(MAC_SHEET_RESULT, returnCode);
  154. rootPane.putClientProperty(MAC_SHEET_SUPPRESS, suppressDialog == 1 ? Boolean.TRUE : Boolean.FALSE);
  155. rootPane.putClientProperty(MAC_SHEET_ID, null);
  156. rootPane.putClientProperty(MacUtil.MAC_NATIVE_WINDOW_SHOWING, null);
  157. }
  158. private static final String MAC_SHEET_RESULT = "mac_sheet_result";
  159. private static final String MAC_SHEET_SUPPRESS = "mac_sheet_suppress";
  160. private static final String MAC_SHEET_ID = "mac_sheet_id";
  161. private MacMessagesImpl() {
  162. }
  163. static {
  164. if (SystemInfo.isMac) {
  165. final ID delegateClass = Foundation.allocateObjcClassPair(Foundation.getObjcClass("NSObject"), "NSAlertDelegate_");
  166. if (!Foundation.addMethod(delegateClass, Foundation.createSelector("alertDidEnd:returnCode:contextInfo:"), SHEET_DID_END, "v*")) {
  167. throw new RuntimeException("Unable to add method to objective-c delegate class!");
  168. }
  169. if (!Foundation.addMethod(delegateClass, Foundation.createSelector("showSheet:"), SIMPLE_SHEET_PANEL, "v*")) {
  170. throw new RuntimeException("Unable to add method to objective-c delegate class!");
  171. }
  172. if (!Foundation.addMethod(delegateClass, Foundation.createSelector("showVariableButtonsSheet:"), VARIABLE_BUTTONS_SHEET_PANEL, "v*")) {
  173. throw new RuntimeException("Unable to add method to objective-c delegate class!");
  174. }
  175. Foundation.registerObjcClassPair(delegateClass);
  176. }
  177. }
  178. @Override
  179. public void showOkMessageDialog(String title, String message, String okText, @Nullable Window window) {
  180. showMessageDialog(title, okText, null, null, message, window);
  181. }
  182. @Override
  183. public void showOkMessageDialog(String title, String message, String okText) {
  184. showMessageDialog(title, okText, null, null, message, null);
  185. }
  186. @Override
  187. public int showYesNoDialog(String title, String message, String yesButton, String noButton, @Nullable Window window) {
  188. return showMessageDialog(title, yesButton, null, noButton, message, window);
  189. }
  190. @Override
  191. public int showYesNoDialog(String title, String message, String yesButton, String noButton, @Nullable Window window,
  192. @Nullable DialogWrapper.DoNotAskOption doNotAskDialogOption) {
  193. return showAlertDialog(title, yesButton, null, noButton, message, window, false, doNotAskDialogOption);
  194. }
  195. @Override
  196. public void showErrorDialog(String title, String message, String okButton, @Nullable Window window) {
  197. showAlertDialog(title, okButton, null, null, message, window, true, null);
  198. }
  199. @Override
  200. public int showYesNoCancelDialog(String title,
  201. String message,
  202. String defaultButton,
  203. String alternateButton,
  204. String otherButton,
  205. Window window,
  206. @Nullable DialogWrapper.DoNotAskOption doNotAskOption) {
  207. return showAlertDialog(title, defaultButton, alternateButton, otherButton, message, window, false, doNotAskOption);
  208. }
  209. public int showMessageDialog(final String title, final String message, final String[] buttons, final boolean errorStyle,
  210. @Nullable Window window, final int defaultOptionIndex,
  211. final int focusedOptionIndex, @Nullable final DialogWrapper.DoNotAskOption doNotAskDialogOption) {
  212. return doForWindowAndTitle(new PairFunction<Pair<Window, String>, JRootPane, Integer>() {
  213. @Override
  214. public Integer fun(Pair<Window, String> windowAndTitle, JRootPane pane) {
  215. String _windowTitle = windowAndTitle.getSecond();
  216. Window _window = windowAndTitle.getFirst();
  217. final ID focusedWindow = MacUtil.findWindowForTitle(_windowTitle);
  218. if (focusedWindow != null) {
  219. String fakeTitle = null;
  220. final FocusTrackback[] focusTrackback = {new FocusTrackback(new Object(), _window, true)};
  221. ID pool = invoke("NSAutoreleasePool", "new");
  222. try {
  223. final ID delegate = invoke(Foundation.getObjcClass("NSAlertDelegate_"), "new");
  224. cfRetain(delegate);
  225. fakeTitle = String.format("MacSheetDialog-%d", delegate.intValue());
  226. final ID buttonsArray = invoke("NSMutableArray", "array");
  227. for (String s : buttons) {
  228. ID s1 = nsString(UIUtil.removeMnemonic(s));
  229. invoke(buttonsArray, "addObject:", s1);
  230. cfRelease(s1);
  231. }
  232. ID paramsArray = invoke("NSArray", "arrayWithObjects:", nsString(title),
  233. // replace % -> %% to avoid formatted parameters (causes SIGTERM)
  234. nsString(StringUtil.stripHtml(message == null ? "" : message, true).replace("%", "%%")),
  235. focusedWindow, nsString(fakeTitle), nsString(errorStyle ? "error" : "-1"),
  236. nsString(doNotAskDialogOption == null || !doNotAskDialogOption.canBeHidden()
  237. // TODO: state=!doNotAsk.shouldBeShown()
  238. ? "-1"
  239. : doNotAskDialogOption.getDoNotShowMessage()),
  240. nsString(Integer.toString(defaultOptionIndex)),
  241. nsString(Integer.toString(focusedOptionIndex)), buttonsArray,
  242. nsString(doNotAskDialogOption != null && !doNotAskDialogOption.isToBeShown() ? "checked" : "-1"), null);
  243. IdeFocusManager.getGlobalInstance().setTypeaheadEnabled(false);
  244. invoke(delegate, "performSelectorOnMainThread:withObject:waitUntilDone:",
  245. Foundation.createSelector("showVariableButtonsSheet:"), paramsArray, false);
  246. }
  247. finally {
  248. invoke(pool, "release");
  249. }
  250. if (fakeTitle != null) {
  251. pane.putClientProperty(MacUtil.MAC_NATIVE_WINDOW_SHOWING, Boolean.TRUE);
  252. pane.putClientProperty(MAC_SHEET_ID, fakeTitle);
  253. MacUtil.startModal(pane);
  254. IdeFocusManager.getGlobalInstance().setTypeaheadEnabled(true);
  255. Integer code = (Integer)pane.getClientProperty(MAC_SHEET_RESULT) - 1000; // see NSAlertFirstButtonReturn for more info
  256. boolean suppress = Boolean.TRUE == pane.getClientProperty(MAC_SHEET_SUPPRESS);
  257. final int cancelCode = buttons.length - 1;
  258. if (doNotAskDialogOption != null && doNotAskDialogOption.canBeHidden()) {
  259. if (cancelCode != code || doNotAskDialogOption.shouldSaveOptionsOnCancel()) {
  260. doNotAskDialogOption.setToBeShown(!suppress, code);
  261. }
  262. }
  263. pane.putClientProperty(MAC_SHEET_RESULT, null);
  264. pane.putClientProperty(MAC_SHEET_SUPPRESS, null);
  265. if (focusTrackback[0] != null &&
  266. !(focusTrackback[0].isSheduledForRestore() || focusTrackback[0].isWillBeSheduledForRestore())) {
  267. focusTrackback[0].setWillBeSheduledForRestore();
  268. IdeFocusManager mgr = IdeFocusManager.findInstanceByComponent(_window);
  269. Runnable r = new Runnable() {
  270. public void run() {
  271. if (focusTrackback[0] != null) focusTrackback[0].restoreFocus();
  272. focusTrackback[0] = null;
  273. }
  274. };
  275. mgr.doWhenFocusSettlesDown(r);
  276. }
  277. return code;
  278. }
  279. }
  280. return -1;
  281. }
  282. }, window);
  283. }
  284. private static int doForWindowAndTitle(PairFunction<Pair<Window, String>, JRootPane, Integer> fun, @Nullable Window window) {
  285. LOG.assertTrue(SwingUtilities.isEventDispatchThread());
  286. JRootPane pane = null;
  287. String _windowTitle = null;
  288. Window _window = window == null ? KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow() : window;
  289. if (_window == null) {
  290. Component focusOwner = IdeFocusManager.findInstance().getFocusOwner();
  291. if (focusOwner != null) {
  292. _window = SwingUtilities.getWindowAncestor(focusOwner);
  293. }
  294. if (_window == null) {
  295. IdeFrame[] allFrames = WindowManager.getInstance().getAllFrames();
  296. if (allFrames.length > 0) {
  297. _window = SwingUtilities.getWindowAncestor(allFrames[0].getComponent());
  298. }
  299. }
  300. }
  301. LOG.assertTrue(_window != null);
  302. if (!_window.isShowing()) {
  303. Container parent = _window.getParent();
  304. if (parent != null && parent instanceof Window) {
  305. _window = (Window)parent;
  306. }
  307. if (!_window.isShowing()) {
  308. Component focusOwner = IdeFocusManager.findInstance().getFocusOwner();
  309. if (focusOwner != null) {
  310. _window = SwingUtilities.getWindowAncestor(focusOwner);
  311. }
  312. }
  313. }
  314. LOG.assertTrue(_window.isShowing(), "Window MUST BE showing in screen!");
  315. if (_window instanceof JFrame) {
  316. JFrame frame = (JFrame)_window;
  317. pane = frame.getRootPane();
  318. _windowTitle = frame.getTitle();
  319. }
  320. else if (_window instanceof JDialog) {
  321. JDialog dialog = (JDialog)_window;
  322. pane = dialog.getRootPane();
  323. _windowTitle = dialog.getTitle();
  324. }
  325. if (_windowTitle == null) {
  326. _window = SwingUtilities.getWindowAncestor(_window);
  327. if (_window instanceof JFrame) {
  328. JFrame frame = (JFrame)_window;
  329. pane = frame.getRootPane();
  330. _windowTitle = frame.getTitle();
  331. }
  332. else if (_window instanceof JDialog) {
  333. JDialog dialog = (JDialog)_window;
  334. pane = dialog.getRootPane();
  335. _windowTitle = dialog.getTitle();
  336. }
  337. }
  338. LOG.assertTrue(_windowTitle != null && _windowTitle.length() > 0 && pane != null, "Window MUST have a title and a root pane!");
  339. return fun.fun(Pair.create(_window, _windowTitle), pane);
  340. }
  341. public static int showAlertDialog(final String title,
  342. final String defaultText,
  343. @Nullable final String alternateText,
  344. @Nullable final String otherText,
  345. final String message,
  346. @Nullable Window window,
  347. final boolean errorStyle,
  348. @Nullable final DialogWrapper.DoNotAskOption doNotAskDialogOption) {
  349. return doForWindowAndTitle(new PairFunction<Pair<Window, String>, JRootPane, Integer>() {
  350. @Override
  351. public Integer fun(Pair<Window, String> windowAndTitle, JRootPane pane) {
  352. String _windowTitle = windowAndTitle.getSecond();
  353. Window _window = windowAndTitle.getFirst();
  354. final ID focusedWindow = MacUtil.findWindowForTitle(_windowTitle);
  355. if (focusedWindow != null) {
  356. String fakeTitle = null;
  357. final FocusTrackback[] focusTrackback = {new FocusTrackback(new Object(), _window, true)};
  358. ID pool = invoke("NSAutoreleasePool", "new");
  359. try {
  360. final ID delegate = invoke(Foundation.getObjcClass("NSAlertDelegate_"), "new");
  361. cfRetain(delegate);
  362. fakeTitle = String.format("MacSheetDialog-%d", delegate.intValue());
  363. ID paramsArray = invoke("NSArray", "arrayWithObjects:", nsString(title), nsString(UIUtil.removeMnemonic(defaultText)),
  364. nsString(otherText == null ? "-1" : UIUtil.removeMnemonic(otherText)),
  365. nsString(alternateText == null ? "-1" : UIUtil.removeMnemonic(alternateText)),
  366. // replace % -> %% to avoid formatted parameters (causes SIGTERM)
  367. nsString(StringUtil.stripHtml(message == null ? "" : message, true).replace("%", "%%")),
  368. focusedWindow, nsString(fakeTitle), nsString(errorStyle ? "error" : "-1"),
  369. nsString(doNotAskDialogOption == null || !doNotAskDialogOption.canBeHidden()
  370. // TODO: state=!doNotAsk.shouldBeShown()
  371. ? "-1"
  372. : doNotAskDialogOption.getDoNotShowMessage()),
  373. nsString(doNotAskDialogOption != null && !doNotAskDialogOption.isToBeShown() ? "checked" : "-1"), null);
  374. IdeFocusManager.getGlobalInstance().setTypeaheadEnabled(false);
  375. invoke(delegate, "performSelectorOnMainThread:withObject:waitUntilDone:",
  376. Foundation.createSelector("showSheet:"), paramsArray, false);
  377. }
  378. finally {
  379. invoke(pool, "release");
  380. }
  381. if (fakeTitle != null) {
  382. pane.putClientProperty(MacUtil.MAC_NATIVE_WINDOW_SHOWING, Boolean.TRUE);
  383. pane.putClientProperty(MAC_SHEET_ID, fakeTitle);
  384. MacUtil.startModal(pane);
  385. IdeFocusManager.getGlobalInstance().setTypeaheadEnabled(true);
  386. Integer result = (Integer)pane.getClientProperty(MAC_SHEET_RESULT);
  387. boolean suppress = Boolean.TRUE == pane.getClientProperty(MAC_SHEET_SUPPRESS);
  388. // DEFAULT = 1
  389. // ALTERNATE = 0
  390. // OTHER = -1 (cancel)
  391. int cancelCode = 1;
  392. int code;
  393. if (alternateText != null) {
  394. // DEFAULT = 0
  395. // ALTERNATE = 1
  396. // CANCEL = 2
  397. cancelCode = 2;
  398. if (result == null) result = 2;
  399. switch (result) {
  400. case 1:
  401. code = 0;
  402. break;
  403. case 0:
  404. code = 1;
  405. break;
  406. case -1: // cancel
  407. default:
  408. code = 2;
  409. break;
  410. }
  411. }
  412. else {
  413. // DEFAULT = 0
  414. // CANCEL = 1
  415. cancelCode = 1;
  416. if (result == null) result = -1;
  417. switch (result) {
  418. case 1:
  419. code = 0;
  420. break;
  421. case -1: // cancel
  422. default:
  423. code = 1;
  424. break;
  425. }
  426. }
  427. if (doNotAskDialogOption != null && doNotAskDialogOption.canBeHidden()) {
  428. if (cancelCode != code || doNotAskDialogOption.shouldSaveOptionsOnCancel()) {
  429. doNotAskDialogOption.setToBeShown(!suppress, code);
  430. }
  431. }
  432. pane.putClientProperty(MAC_SHEET_RESULT, null);
  433. pane.putClientProperty(MAC_SHEET_SUPPRESS, null);
  434. if (focusTrackback[0] != null &&
  435. !(focusTrackback[0].isSheduledForRestore() || focusTrackback[0].isWillBeSheduledForRestore())) {
  436. focusTrackback[0].setWillBeSheduledForRestore();
  437. IdeFocusManager mgr = IdeFocusManager.findInstanceByComponent(_window);
  438. Runnable r = new Runnable() {
  439. public void run() {
  440. if (focusTrackback[0] != null) focusTrackback[0].restoreFocus();
  441. focusTrackback[0] = null;
  442. }
  443. };
  444. mgr.doWhenFocusSettlesDown(r);
  445. }
  446. return code;
  447. }
  448. }
  449. return -1;
  450. }
  451. }, window);
  452. }
  453. public static int showMessageDialog(String title,
  454. String okText,
  455. @Nullable String alternateText,
  456. @Nullable String cancelText,
  457. String message,
  458. @Nullable Window window) {
  459. return showAlertDialog(title, okText, alternateText, cancelText, message, window, false, null);
  460. }
  461. }