cucumber, qick fix: preselection in new step dialog
[fedora-idea.git] / platform / platform-impl / src / com / intellij / openapi / ui / impl / DialogWrapperPeerImpl.java
blob25aef17458d230b2ad4f8d404db73111d63e21f6
1 package com.intellij.openapi.ui.impl;
3 import com.intellij.ide.DataManager;
4 import com.intellij.ide.IdeEventQueue;
5 import com.intellij.ide.impl.TypeSafeDataProviderAdapter;
6 import com.intellij.ide.ui.UISettings;
7 import com.intellij.openapi.Disposable;
8 import com.intellij.openapi.actionSystem.*;
9 import com.intellij.openapi.application.Application;
10 import com.intellij.openapi.application.ApplicationManager;
11 import com.intellij.openapi.application.impl.LaterInvocator;
12 import com.intellij.openapi.command.CommandProcessor;
13 import com.intellij.openapi.command.CommandProcessorEx;
14 import com.intellij.openapi.diagnostic.Logger;
15 import com.intellij.openapi.project.DumbAware;
16 import com.intellij.openapi.project.Project;
17 import com.intellij.openapi.ui.DialogWrapper;
18 import com.intellij.openapi.ui.DialogWrapperDialog;
19 import com.intellij.openapi.ui.DialogWrapperPeer;
20 import com.intellij.openapi.ui.TestableUi;
21 import com.intellij.openapi.ui.popup.StackingPopupDispatcher;
22 import com.intellij.openapi.util.*;
23 import com.intellij.openapi.util.registry.Registry;
24 import com.intellij.openapi.wm.FocusCommand;
25 import com.intellij.openapi.wm.IdeFocusManager;
26 import com.intellij.openapi.wm.KeyEventProcessor;
27 import com.intellij.openapi.wm.WindowManager;
28 import com.intellij.openapi.wm.ex.WindowManagerEx;
29 import com.intellij.openapi.wm.impl.IdeFrameImpl;
30 import com.intellij.openapi.wm.impl.IdeGlassPaneImpl;
31 import com.intellij.ui.AppUIUtil;
32 import com.intellij.ui.FocusTrackback;
33 import com.intellij.ui.ScreenUtil;
34 import com.intellij.ui.SpeedSearchBase;
35 import com.intellij.ui.popup.StackingPopupDispatcherImpl;
36 import com.intellij.util.ui.UIUtil;
37 import org.jetbrains.annotations.NonNls;
38 import org.jetbrains.annotations.NotNull;
39 import org.jetbrains.annotations.Nullable;
41 import javax.swing.*;
42 import java.awt.*;
43 import java.awt.event.*;
44 import java.awt.image.BufferStrategy;
45 import java.lang.ref.WeakReference;
46 import java.lang.reflect.Field;
47 import java.lang.reflect.Method;
48 import java.util.ArrayList;
49 import java.util.List;
50 import java.util.Map;
52 public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTrackbackProvider {
53 private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.ui.DialogWrapper");
55 private DialogWrapper myWrapper;
56 private MyDialog myDialog;
57 private boolean myCanBeParent = true;
59 * Default dialog's actions.
61 private WindowManagerEx myWindowManager;
62 private final java.util.List<Runnable> myDisposeActions = new ArrayList<Runnable>();
63 private Project myProject;
65 private ActionCallback myWindowFocusedCallback = new ActionCallback("DialogFocusedCallback");
66 private ActionCallback myTypeAheadDone = new ActionCallback("DialogTypeAheadDone");
68 /**
69 * Creates modal <code>DialogWrapper</code>. The currently active window will be the dialog's parent.
71 * @param project parent window for the dialog will be calculated based on focused window for the
72 * specified <code>project</code>. This parameter can be <code>null</code>. In this case parent window
73 * will be suggested based on current focused window.
74 * @param canBeParent specifies whether the dialog can be parent for other windows. This parameter is used
75 * by <code>WindowManager</code>.
77 protected DialogWrapperPeerImpl(DialogWrapper wrapper, Project project, boolean canBeParent) {
78 myWrapper = wrapper;
79 myWindowManager = null;
80 Application application = ApplicationManager.getApplication();
81 if (application != null && application.hasComponent(WindowManager.class)) {
82 myWindowManager = (WindowManagerEx)WindowManager.getInstance();
85 Window window = null;
86 if (myWindowManager != null) {
88 if (project == null) {
89 project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
92 myProject = project;
94 window = myWindowManager.suggestParentWindow(project);
95 if (window == null) {
96 Window focusedWindow = myWindowManager.getMostRecentFocusedWindow();
97 if (focusedWindow instanceof IdeFrameImpl) {
98 window = focusedWindow;
103 Window owner;
104 if (window != null) {
105 owner = window;
107 else {
108 owner = JOptionPane.getRootFrame();
111 createDialog(owner, canBeParent);
114 protected DialogWrapperPeerImpl(DialogWrapper wrapper, boolean canBeParent) {
115 this(wrapper, (Project)null, canBeParent);
119 * @param parent parent component whicg is used to canculate heavy weight window ancestor.
120 * <code>parent</code> cannot be <code>null</code> and must be showing.
122 protected DialogWrapperPeerImpl(DialogWrapper wrapper, @NotNull Component parent, boolean canBeParent) {
123 myWrapper = wrapper;
124 if (!parent.isShowing() && parent != JOptionPane.getRootFrame()) {
125 throw new IllegalArgumentException("parent must be showing: " + parent);
127 myWindowManager = null;
128 Application application = ApplicationManager.getApplication();
129 if (application != null && application.hasComponent(WindowManager.class)) {
130 myWindowManager = (WindowManagerEx)WindowManager.getInstance();
133 Window owner = parent instanceof Window ? (Window)parent : (Window)SwingUtilities.getAncestorOfClass(Window.class, parent);
134 if (!(owner instanceof Dialog) && !(owner instanceof Frame)) {
135 owner = JOptionPane.getRootFrame();
137 createDialog(owner, canBeParent);
140 public DialogWrapperPeerImpl(final DialogWrapper wrapper, final boolean canBeParent, final boolean tryToolkitModal) {
141 myWrapper = wrapper;
142 myWindowManager = null;
143 Application application = ApplicationManager.getApplication();
144 if (application != null && application.hasComponent(WindowManager.class)) {
145 myWindowManager = (WindowManagerEx)WindowManager.getInstance();
147 if (UIUtil.hasJdk6Dialogs()) {
148 createDialog(null, canBeParent);
149 if (tryToolkitModal) {
150 UIUtil.setToolkitModal(myDialog);
153 else {
154 createDialog(JOptionPane.getRootFrame(), canBeParent);
158 public void setUndecorated(boolean undecorated) {
159 myDialog.setUndecorated(undecorated);
162 public void addMouseListener(MouseListener listener) {
163 myDialog.addMouseListener(listener);
166 public void addMouseListener(MouseMotionListener listener) {
167 myDialog.addMouseMotionListener(listener);
170 public void addKeyListener(KeyListener listener) {
171 myDialog.addKeyListener(listener);
174 private void createDialog(Window owner, boolean canBeParent) {
175 if (owner instanceof Frame) {
176 myDialog = new MyDialog((Frame)owner, myWrapper, myProject, myWindowFocusedCallback, myTypeAheadDone);
178 else {
179 myDialog = new MyDialog((Dialog)owner, myWrapper, myProject, myWindowFocusedCallback, myTypeAheadDone);
181 myDialog.setModal(true);
182 myCanBeParent = canBeParent;
187 public void toFront() {
188 myDialog.toFront();
191 public void toBack() {
192 myDialog.toBack();
195 protected void dispose() {
196 LOG.assertTrue(EventQueue.isDispatchThread(), "Access is allowed from event dispatch thread only");
197 for (Runnable runnable : myDisposeActions) {
198 runnable.run();
200 myDisposeActions.clear();
201 myDialog.remove(myDialog.getRootPane());
203 Runnable disposer = new Runnable() {
204 public void run() {
205 myDialog.dispose();
206 myProject = null;
208 if (myWindowManager == null) {
209 myDialog.dispose();
211 else {
212 myWindowManager.hideDialog(myDialog, myProject);
218 if (EventQueue.isDispatchThread()) {
219 disposer.run();
221 else {
222 SwingUtilities.invokeLater(disposer);
226 private boolean isProgressDialog() {
227 return myWrapper.isModalProgress();
230 @Nullable
231 public Container getContentPane() {
232 return getRootPane() != null ? myDialog.getContentPane() : null;
236 * @see javax.swing.JDialog#validate
238 public void validate() {
239 myDialog.validate();
243 * @see javax.swing.JDialog#repaint
245 public void repaint() {
246 myDialog.repaint();
249 public Window getOwner() {
250 return myDialog.getOwner();
253 public Window getWindow() {
254 return myDialog;
257 public JRootPane getRootPane() {
258 return myDialog.getRootPane();
261 public Dimension getSize() {
262 return myDialog.getSize();
265 public String getTitle() {
266 return myDialog.getTitle();
270 * @see java.awt.Window#pack
272 public void pack() {
273 myDialog.pack();
276 public void setIconImages(final List<Image> image) {
277 UIUtil.updateDialogIcon(myDialog, image);
280 public void setAppIcons() {
281 setIconImages(AppUIUtil.getAppIconImages());
284 public Dimension getPreferredSize() {
285 return myDialog.getPreferredSize();
288 public void setModal(boolean modal) {
289 myDialog.setModal(modal);
292 public boolean isVisible() {
293 return myDialog.isVisible();
296 public boolean isShowing() {
297 return myDialog.isShowing();
300 public void setSize(int width, int height) {
301 myDialog.setSize(width, height);
304 public void setTitle(String title) {
305 myDialog.setTitle(title);
308 public void isResizable() {
309 myDialog.isResizable();
312 public void setResizable(boolean resizable) {
313 myDialog.setResizable(resizable);
316 public Point getLocation() {
317 return myDialog.getLocation();
320 public void setLocation(Point p) {
321 myDialog.setLocation(p);
324 public void setLocation(int x, int y) {
325 myDialog.setLocation(x, y);
328 public void show() {
329 LOG.assertTrue(EventQueue.isDispatchThread(), "Access is allowed from event dispatch thread only");
331 final AnCancelAction anCancelAction = new AnCancelAction();
332 final JRootPane rootPane = getRootPane();
333 anCancelAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)), rootPane);
334 myDisposeActions.add(new Runnable() {
335 public void run() {
336 anCancelAction.unregisterCustomShortcutSet(rootPane);
340 if (!myCanBeParent && myWindowManager != null) {
341 myWindowManager.doNotSuggestAsParent(myDialog);
344 final CommandProcessorEx commandProcessor =
345 ApplicationManager.getApplication() != null ? (CommandProcessorEx)CommandProcessor.getInstance() : null;
346 final boolean appStarted = commandProcessor != null;
348 if (myDialog.isModal() && !isProgressDialog()) {
350 if (ApplicationManager.getApplication() != null) {
351 if (ApplicationManager.getApplication().getCurrentWriteAction(null) != null) {
352 LOG.warn(
353 "Showing of a modal dialog inside write-action may be dangerous and resulting in unpredictable behavior! Current modalityState=" + ModalityState.current(), new Exception());
357 if (appStarted) {
358 commandProcessor.enterModal();
359 LaterInvocator.enterModal(myDialog);
363 if (appStarted) {
364 hidePopupsIfNeeded();
367 try {
368 myDialog.show();
370 finally {
371 if (myDialog.isModal() && !isProgressDialog()) {
372 if (appStarted) {
373 commandProcessor.leaveModal();
374 LaterInvocator.leaveModal(myDialog);
380 //[kirillk] for now it only deals with the TaskWindow under Mac OS X: modal dialogs are shown behind JBPopup
382 //hopefully this whole code will go away
383 private void hidePopupsIfNeeded() {
384 if (!SystemInfo.isMac) return;
386 StackingPopupDispatcherImpl.getInstance().hidePersistentPopups();
387 myDisposeActions.add(new Runnable() {
388 public void run() {
389 StackingPopupDispatcherImpl.getInstance().restorePersistentPopups();
394 public FocusTrackback getFocusTrackback() {
395 return myDialog.getFocusTrackback();
398 private class AnCancelAction extends AnAction implements DumbAware {
399 public void update(AnActionEvent e) {
400 Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
401 e.getPresentation().setEnabled(false);
402 if (focusOwner instanceof JComponent && SpeedSearchBase.hasActiveSpeedSearch((JComponent)focusOwner)) {
403 return;
406 if (StackingPopupDispatcher.getInstance().isPopupFocused()) return;
408 if (focusOwner instanceof JTree) {
409 JTree tree = (JTree)focusOwner;
410 if (!tree.isEditing()) {
411 e.getPresentation().setEnabled(true);
414 else if (focusOwner instanceof JTable) {
415 JTable table = (JTable)focusOwner;
416 if (!table.isEditing()) {
417 e.getPresentation().setEnabled(true);
422 public void actionPerformed(AnActionEvent e) {
423 myWrapper.doCancelAction(e.getInputEvent());
428 private static class MyDialog extends JDialog implements DialogWrapperDialog, DataProvider, FocusTrackback.Provider, TestableUi {
429 private final WeakReference<DialogWrapper> myDialogWrapper;
431 * Initial size of the dialog. When the dialog is being closed and
432 * current size of the dialog is not equals to the initial sizethen the
433 * current (changed) size is stored in the <code>DimensionService</code>.
435 private Dimension myInitialSize;
436 private String myDimensionServiceKey;
437 private boolean myOpened = false;
439 private FocusTrackback myFocusTrackback;
440 private MyDialog.MyWindowListener myWindowListener;
441 private MyDialog.MyComponentListener myComponentListener;
443 private final WeakReference<Project> myProject;
444 private ActionCallback myFocusedCallback;
445 private ActionCallback myTypeAheadDone;
447 public MyDialog(Dialog owner, DialogWrapper dialogWrapper, Project project, ActionCallback focused, ActionCallback typeAheadDone) {
448 super(owner);
449 myDialogWrapper = new WeakReference<DialogWrapper>(dialogWrapper);
450 myProject = project != null ? new WeakReference<Project>(project) : null;
451 initDialog(focused, typeAheadDone);
454 public MyDialog(Frame owner, DialogWrapper dialogWrapper, Project project, ActionCallback focused, ActionCallback typeAheadDone) {
455 super(owner);
456 myDialogWrapper = new WeakReference<DialogWrapper>(dialogWrapper);
457 myProject = project != null ? new WeakReference<Project>(project) : null;
458 initDialog(focused, typeAheadDone);
461 private void initDialog(ActionCallback focused, ActionCallback typeAheadDone) {
462 myFocusedCallback = focused;
463 myTypeAheadDone = typeAheadDone;
465 final long typeAhead = getDialogWrapper().getTypeAheadTimeoutMs();
466 if (typeAhead <= 0) {
467 myTypeAheadDone.setDone();
470 setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
471 myWindowListener = new MyWindowListener();
472 addWindowListener(myWindowListener);
473 myComponentListener = new MyComponentListener();
474 addComponentListener(myComponentListener);
477 public void putInfo(Map<String, String> info) {
478 info.put("dialog", getTitle());
481 public FocusTrackback getFocusTrackback() {
482 return myFocusTrackback;
485 public DialogWrapper getDialogWrapper() {
486 return myDialogWrapper.get();
489 public void centerInParent() {
490 setLocationRelativeTo(getOwner());
493 public Object getData(String dataId) {
494 final DialogWrapper wrapper = myDialogWrapper.get();
495 if (wrapper instanceof DataProvider) {
496 return ((DataProvider)wrapper).getData(dataId);
498 else if (wrapper instanceof TypeSafeDataProvider) {
499 TypeSafeDataProviderAdapter adapter = new TypeSafeDataProviderAdapter((TypeSafeDataProvider)wrapper);
500 return adapter.getData(dataId);
502 return null;
505 public void setSize(int width, int height) {
506 Point location = getLocation();
507 Rectangle rect = new Rectangle(location.x, location.y, width, height);
508 ScreenUtil.fitToScreen(rect);
509 if (location.x != rect.x || location.y != rect.y) {
510 setLocation(rect.x, rect.y);
513 super.setSize(rect.width, rect.height);
516 public void setBounds(int x, int y, int width, int height) {
517 Rectangle rect = new Rectangle(x, y, width, height);
518 ScreenUtil.fitToScreen(rect);
519 super.setBounds(rect.x, rect.y, rect.width, rect.height);
522 public void setBounds(Rectangle r) {
523 ScreenUtil.fitToScreen(r);
524 super.setBounds(r);
527 protected JRootPane createRootPane() {
528 return new DialogRootPane();
531 public void show() {
532 myFocusTrackback = new FocusTrackback(myDialogWrapper, this, true);
534 final DialogWrapper dialogWrapper = getDialogWrapper();
536 pack();
537 setSize((int)(getWidth() * dialogWrapper.getHorizontalStretch()), (int)(getHeight() * dialogWrapper.getVerticalStretch()));
539 // Restore dialog's size and location
541 myDimensionServiceKey = dialogWrapper.getDimensionKey();
542 Point location = null;
544 if (myDimensionServiceKey != null) {
545 final Project projectGuess = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(this));
546 location = DimensionService.getInstance().getLocation(myDimensionServiceKey, projectGuess);
547 Dimension size = DimensionService.getInstance().getSize(myDimensionServiceKey, projectGuess);
548 if (size != null) {
549 myInitialSize = (Dimension)size.clone();
550 setSize(myInitialSize);
554 if (myInitialSize == null) {
555 myInitialSize = getSize();
558 if (location == null) {
559 location = dialogWrapper.getInitialLocation();
562 if (location != null) {
563 setLocation(location);
565 else {
566 setLocationRelativeTo(getOwner());
569 final Rectangle bounds = getBounds();
570 ScreenUtil.fitToScreen(bounds);
571 setBounds(bounds);
573 addWindowListener(new WindowAdapter() {
574 public void windowActivated(final WindowEvent e) {
575 final DialogWrapper wrapper = getDialogWrapper();
576 if (wrapper != null && myFocusTrackback != null) {
577 myFocusTrackback.registerFocusComponent(new FocusTrackback.ComponentQuery() {
578 public Component getComponent() {
579 return wrapper.getPreferredFocusedComponent();
585 public void windowDeactivated(final WindowEvent e) {
586 if (!isModal()) {
587 final Ref<IdeFocusManager> focusManager = new Ref<IdeFocusManager>(null);
588 if (myProject != null && myProject.get() != null && !myProject.get().isDisposed()) {
589 focusManager.set(IdeFocusManager.getInstance(myProject.get()));
590 focusManager.get().doWhenFocusSettlesDown(new Runnable() {
591 public void run() {
592 disposeFocusTrackbackIfNoChildWindowFocused(focusManager.get());
596 else {
597 disposeFocusTrackbackIfNoChildWindowFocused(focusManager.get());
603 if (Registry.is("actionSystem.fixLostTyping")) {
604 final IdeEventQueue queue = IdeEventQueue.getInstance();
605 if (queue != null) {
606 queue.getKeyEventDispatcher().resetState();
609 if (myProject != null) {
610 Project project = myProject.get();
611 if (project != null && !project.isDisposed() && project.isInitialized()) {
612 IdeFocusManager.findInstanceByComponent(this).requestFocus(new MyFocusCommand(dialogWrapper), true);
617 super.show();
620 private void disposeFocusTrackbackIfNoChildWindowFocused(@Nullable IdeFocusManager focusManager) {
621 if (myFocusTrackback == null) return;
623 final DialogWrapper wrapper = myDialogWrapper.get();
624 if (wrapper == null || !wrapper.isShowing()) {
625 myFocusTrackback.dispose();
626 return;
629 if (focusManager != null) {
630 final Component c = focusManager.getFocusedDescendantFor(wrapper.getContentPane());
631 if (c == null) {
632 myFocusTrackback.dispose();
635 else {
636 final Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
637 if (owner == null || !SwingUtilities.isDescendingFrom(owner, wrapper.getContentPane())) {
638 myFocusTrackback.dispose();
643 @Deprecated
644 public void hide() {
645 super.hide();
646 if (myFocusTrackback != null) {
647 myFocusTrackback.restoreFocus();
651 public void dispose() {
652 if (isShowing()) {
653 hide();
656 if (myWindowListener != null) {
657 myWindowListener.saveSize();
658 removeWindowListener(myWindowListener);
659 myWindowListener = null;
661 if (myComponentListener != null) {
662 removeComponentListener(myComponentListener);
663 myComponentListener = null;
666 if (myFocusTrackback != null && !myFocusTrackback.isSheduledForRestore()) {
667 myFocusTrackback.dispose();
668 myFocusTrackback = null;
672 final BufferStrategy strategy = getBufferStrategy();
673 if (strategy != null) {
674 try {
675 Method method = strategy.getClass().getMethod("dispose"); // added in JDK 1.6 so cannot call directly
676 method.invoke(strategy);
678 catch (Exception ex) {
679 // ignore
682 super.dispose();
685 if (rootPane != null) { // Workaround for bug in native code to hold rootPane
686 try {
687 Field field = rootPane.getClass().getDeclaredField("glassPane");
688 field.setAccessible(true);
689 field.set(rootPane, null);
691 field = rootPane.getClass().getDeclaredField("contentPane");
692 field.setAccessible(true);
693 field.set(rootPane, null);
694 rootPane = null;
696 field = Window.class.getDeclaredField("windowListener");
697 field.setAccessible(true);
698 field.set(this, null);
700 catch (Exception e) {
704 // http://bugs.sun.com/view_bug.do?bug_id=6614056
705 try {
706 final Field field = Dialog.class.getDeclaredField("modalDialogs");
707 field.setAccessible(true);
708 final List<?> list = (List<?>)field.get(null);
709 list.remove(this);
711 catch (final Exception ex) {
715 @Override
716 public Component getMostRecentFocusOwner() {
717 if (!myOpened) {
718 final DialogWrapper wrapper = getDialogWrapper();
719 if (wrapper != null) {
720 JComponent toFocus = wrapper.getPreferredFocusedComponent();
721 if (toFocus != null) {
722 return toFocus;
726 return super.getMostRecentFocusOwner();
729 @Override
730 public void paint(Graphics g) {
731 UIUtil.applyRenderingHints(g);
732 super.paint(g);
735 private class MyWindowListener extends WindowAdapter {
736 public void windowClosing(WindowEvent e) {
737 DialogWrapper dialogWrapper = getDialogWrapper();
738 if (dialogWrapper.shouldCloseOnCross()) {
739 dialogWrapper.doCancelAction(e);
743 public void windowClosed(WindowEvent e) {
744 saveSize();
747 public void saveSize() {
748 if (myDimensionServiceKey != null &&
749 myInitialSize != null &&
750 myOpened) { // myInitialSize can be null only if dialog is disposed before first showing
751 final Project projectGuess = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(MyDialog.this));
753 // Save location
754 Point location = getLocation();
755 DimensionService.getInstance().setLocation(myDimensionServiceKey, location, projectGuess);
756 // Save size
757 Dimension size = getSize();
758 if (!myInitialSize.equals(size)) {
759 DimensionService.getInstance().setSize(myDimensionServiceKey, size, projectGuess);
761 myOpened = false;
765 public void windowOpened(final WindowEvent e) {
766 SwingUtilities.invokeLater(new Runnable() {
767 public void run() {
768 myOpened = true;
769 final DialogWrapper activeWrapper = getActiveWrapper();
770 if (activeWrapper == null) {
771 myFocusedCallback.setRejected();
772 myTypeAheadDone.setRejected();
773 return;
776 JComponent toFocus = activeWrapper.getPreferredFocusedComponent();
777 if (toFocus == null) {
778 toFocus = getRootPane().getDefaultButton();
781 moveMousePointerOnButton(getRootPane().getDefaultButton());
782 setupSelectionOnPreferredComponent(toFocus);
784 if (toFocus != null) {
785 final JComponent toRequest = toFocus;
786 SwingUtilities.invokeLater(new Runnable() {
787 public void run() {
788 IdeFocusManager.findInstanceByComponent(e.getWindow()).requestFocus(toRequest, true);
789 notifyFocused(activeWrapper);
792 } else {
793 notifyFocused(activeWrapper);
799 private void notifyFocused(DialogWrapper wrapper) {
800 myFocusedCallback.setDone();
801 final long timeout = wrapper.getTypeAheadTimeoutMs();
802 if (timeout > 0) {
803 SimpleTimer.getInstance().setUp(new EdtRunnable() {
804 public void runEdt() {
805 myTypeAheadDone.setDone();
807 }, timeout);
811 private DialogWrapper getActiveWrapper() {
812 DialogWrapper activeWrapper = getDialogWrapper();
813 if (activeWrapper == null || !activeWrapper.isShowing()) {
814 return null;
817 return activeWrapper;
820 private void moveMousePointerOnButton(final JButton button) {
821 Application application = ApplicationManager.getApplication();
822 if (application != null && application.hasComponent(UISettings.class)) {
823 if (button != null && UISettings.getInstance().MOVE_MOUSE_ON_DEFAULT_BUTTON) {
824 Point p = button.getLocationOnScreen();
825 Rectangle r = button.getBounds();
826 try {
827 Robot robot = new Robot();
828 robot.mouseMove(p.x + r.width / 2, p.y + r.height / 2);
830 catch (AWTException exc) {
831 exc.printStackTrace();
838 private class MyComponentListener extends ComponentAdapter {
839 @SuppressWarnings({"RefusedBequest"})
840 public void componentResized(ComponentEvent e) {
841 final JRootPane pane = getRootPane();
842 if (pane == null) return;
843 final Dimension minSize = pane.getMinimumSize();
844 final Dimension size = pane.getSize();
845 final Dimension winSize = getSize();
846 if (minSize.width > size.width) {
847 winSize.width += minSize.width - size.width;
849 if (minSize.height > size.height) {
850 winSize.height += minSize.height - size.height;
853 if (!winSize.equals(getSize())) {
854 SwingUtilities.invokeLater(new Runnable() {
855 public void run() {
856 if (isShowing()) {
857 setSize(winSize);
865 private class DialogRootPane extends JRootPane implements DataProvider {
867 private final boolean myGlassPaneIsSet;
869 private DialogRootPane() {
870 setGlassPane(new IdeGlassPaneImpl(this));
871 myGlassPaneIsSet = true;
874 @Override
875 public void setGlassPane(final Component glass) {
876 if (myGlassPaneIsSet) {
877 LOG.warn("Setting of glass pane for DialogWrapper is prohibited", new Exception());
878 return;
881 super.setGlassPane(glass);
884 public Object getData(@NonNls String dataId) {
885 final DialogWrapper wrapper = myDialogWrapper.get();
886 return PlatformDataKeys.UI_DISPOSABLE.getName().equals(dataId) ? wrapper.getDisposable() : null;
891 private class MyFocusCommand extends FocusCommand implements KeyEventProcessor {
893 private Context myContextOnFinish;
894 private ArrayList<KeyEvent> myEvents = new ArrayList<KeyEvent>();
895 private DialogWrapper myWrapper;
897 private MyFocusCommand(DialogWrapper wrapper) {
898 myWrapper = getDialogWrapper();
900 Disposer.register(wrapper.getDisposable(), new Disposable() {
901 public void dispose() {
902 if (!myTypeAheadDone.isProcessed()) {
903 myTypeAheadDone.setDone();
906 flushEvents();
911 public ActionCallback run() {
912 return myTypeAheadDone;
915 @Override
916 public KeyEventProcessor getProcessor() {
917 return this;
920 public Boolean dispatch(KeyEvent e, Context context) {
921 if (myWrapper == null || myTypeAheadDone.isProcessed()) return null;
923 myEvents.addAll(context.getQueue());
924 context.getQueue().clear();
926 if (isToDipatchToDialogNow(e)) {
927 return false;
928 } else {
929 myEvents.add(e);
930 return true;
934 private boolean isToDipatchToDialogNow(KeyEvent e) {
935 return e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_ESCAPE || e.getKeyCode() == KeyEvent.VK_TAB;
938 public void finish(Context context) {
939 myContextOnFinish = context;
942 private void flushEvents() {
943 if (myWrapper.isToDispatchTypeAhead() && myContextOnFinish != null) {
944 myContextOnFinish.dispatch(myEvents);
950 private static void setupSelectionOnPreferredComponent(final JComponent component) {
951 if (component instanceof JTextField) {
952 JTextField field = (JTextField)component;
953 String text = field.getText();
954 if (text != null && field.getClientProperty(HAVE_INITIAL_SELECTION) == null) {
955 field.setSelectionStart(0);
956 field.setSelectionEnd(text.length());
959 else if (component instanceof JComboBox) {
960 JComboBox combobox = (JComboBox)component;
961 combobox.getEditor().selectAll();
965 public void setContentPane(JComponent content) {
966 myDialog.setContentPane(content);
969 public void centerInParent() {
970 myDialog.centerInParent();