diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooser.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooser.java index c51fef0c4b22..65d8582e2d28 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooser.java +++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooser.java @@ -87,7 +87,7 @@ public class FileChooser { @Nullable final Project project, @Nullable final VirtualFile toSelect, @NotNull final Consumer> callback) { - chooseFiles(descriptor, project, KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(), toSelect, callback); + chooseFiles(descriptor, project, KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(), toSelect, callback); } /** diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java index 9dd912540ece..e15b6351e343 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java @@ -54,6 +54,7 @@ import com.intellij.ui.mac.foundation.MacUtil; import com.intellij.util.IJSwingUtilities; import com.intellij.util.ReflectionUtil; import com.intellij.util.ui.JBInsets; +import com.intellij.util.ui.OwnerOptional; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -175,18 +176,16 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra */ protected DialogWrapperPeerImpl(@NotNull DialogWrapper wrapper, @NotNull Component parent, boolean canBeParent) { myWrapper = wrapper; - if (!parent.isShowing()) { - throw new IllegalArgumentException("parent must be showing: " + parent); - } + myWindowManager = null; Application application = ApplicationManager.getApplication(); if (application != null && application.hasComponent(WindowManager.class)) { myWindowManager = (WindowManagerEx)WindowManager.getInstance(); } - Window owner = parent instanceof Window ? (Window)parent : (Window)SwingUtilities.getAncestorOfClass(Window.class, parent); - if (!(owner instanceof Dialog) && !(owner instanceof Frame)) { - owner = JOptionPane.getRootFrame(); + Window owner = OwnerOptional.fromComponent(parent).get(); + if (!owner.isShowing()) { + throw new IllegalArgumentException("owner must be showing: " + owner); } createDialog(owner, canBeParent); } @@ -219,7 +218,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra @Deprecated public DialogWrapperPeerImpl(@NotNull DialogWrapper wrapper,final Window owner, final boolean canBeParent, final boolean applicationModalIfPossible) { - this(wrapper, owner, canBeParent, applicationModalIfPossible ? DialogWrapper.IdeModalityType.IDE : DialogWrapper.IdeModalityType.PROJECT); + this(wrapper, owner, canBeParent, applicationModalIfPossible ? DialogWrapper.IdeModalityType.IDE : DialogWrapper.IdeModalityType.PROJECT); } @Override @@ -496,7 +495,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra if (StackingPopupDispatcher.getInstance().isPopupFocused()) return; JTree tree = UIUtil.getParentOfType(JTree.class, focusOwner); JTable table = UIUtil.getParentOfType(JTable.class, focusOwner); - + if (tree != null || table != null) { if (hasNoEditingTreesOrTablesUpward(focusOwner)) { e.getPresentation().setEnabled(true); diff --git a/platform/platform-impl/src/com/intellij/ui/mac/MacPathChooserDialog.java b/platform/platform-impl/src/com/intellij/ui/mac/MacPathChooserDialog.java index 843caae83081..37f85924d2e8 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/MacPathChooserDialog.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/MacPathChooserDialog.java @@ -26,18 +26,15 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.PathChooserDialog; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.ui.popup.StackingPopupDispatcher; -import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFrame; import com.intellij.openapi.wm.WindowManager; import com.intellij.ui.UIBundle; -import com.intellij.ui.popup.AbstractPopup; import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; -import com.intellij.util.ui.UIUtil; +import com.intellij.util.ui.OwnerOptional; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -54,23 +51,25 @@ import java.util.stream.Stream; public class MacPathChooserDialog implements PathChooserDialog { - private final FileDialog myFileDialog; + private FileDialog myFileDialog; private final FileChooserDescriptor myFileChooserDescriptor; private final Component myParent; private final String myTitle; public MacPathChooserDialog(FileChooserDescriptor descriptor, Component parent, Project project) { - //StackingPopupDispatcher.getInstance().hidePersistentPopups(); - //myDisposeActions.add(() -> StackingPopupDispatcher.getInstance().restorePersistentPopups()); - - myFileDialog = parent != null - ? createFileDialogWithOwner(findOwnerByComponent(parent), descriptor.getTitle(), FileDialog.LOAD) - : createFileDialogWithoutOwner(descriptor.getTitle(), FileDialog.LOAD); - myFileChooserDescriptor = descriptor; myParent = parent; myTitle = getChooserTitle(descriptor); + + Consumer dialogConsumer = owner -> myFileDialog = new FileDialog(owner, myTitle, FileDialog.LOAD); + Consumer frameConsumer = owner -> myFileDialog = new FileDialog(owner, myTitle, FileDialog.LOAD); + + OwnerOptional + .fromComponent(parent) + .ifDialog(dialogConsumer) + .ifFrame(frameConsumer) + .ifNull(frameConsumer); } private static String getChooserTitle(final FileChooserDescriptor descriptor) { @@ -139,64 +138,6 @@ public class MacPathChooserDialog implements PathChooserDialog { } } - @NotNull - private static Window findOwnerByComponent(@NotNull Component component) { - return (component instanceof Window) ? (Window) component : SwingUtilities.getWindowAncestor(component); - } - - @NotNull - private static FileDialog createFileDialogWithOwner(@NotNull Window owner, String title, int mode) { - FileDialog fileDialog; - - IdePopupManager manager = IdeEventQueue.getInstance().getPopupManager(); - - if (manager.isPopupWindow(owner)) { - - manager.closeAllPopups(); - - owner = owner.getOwner(); - - while (owner != null - && !(owner instanceof Dialog) - && !(owner instanceof Frame)) { - owner = owner.getOwner(); - } - } - - if (owner instanceof Dialog) { - Dialog ownerDialog = (Dialog)owner; - if (ownerDialog.isModal()) { - owner = ownerDialog; - } - else { - while (owner instanceof Dialog && !((Dialog)owner).isModal()) { - owner = owner.getOwner(); - } - } - } - - if (owner == null) { - fileDialog = createFileDialogWithoutOwner(title, mode); - } - else { - if (owner instanceof Frame) { - if (owner instanceof IdeFrame.Child) { - IdeFrame.Child ideFrameChild = (IdeFrame.Child)owner; - owner = WindowManager.getInstance().getFrame(ideFrameChild.getProject()); - } - fileDialog = new FileDialog((Frame)owner, title, mode); - } - else if (owner instanceof Dialog) { - fileDialog = new FileDialog((Dialog)owner, title, mode); - } - else { - throw new RuntimeException("Owner should be a frame or a dialog"); - } - } - - return fileDialog; - } - @NotNull private static FileDialog createFileDialogWithoutOwner(String title, int load) { // This is bad. But sometimes we do not have any windows at all. diff --git a/platform/platform-impl/src/com/intellij/util/ui/OwnerOptional.java b/platform/platform-impl/src/com/intellij/util/ui/OwnerOptional.java new file mode 100644 index 000000000000..ad88b852ea0f --- /dev/null +++ b/platform/platform-impl/src/com/intellij/util/ui/OwnerOptional.java @@ -0,0 +1,104 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.ui; + +import com.intellij.ide.IdeEventQueue; +import com.intellij.ide.IdePopupManager; +import com.intellij.openapi.wm.IdeFrame; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.util.Consumer; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Denis Fokin + */ +public class OwnerOptional { + + @NotNull + private static Window findOwnerByComponent(@NotNull Component component) { + return (component instanceof Window) ? (Window) component : SwingUtilities.getWindowAncestor(component); + } + + private Window myPermanentOwner; + + private OwnerOptional(Window permanentOwner) { + this.myPermanentOwner = permanentOwner; + } + + public static OwnerOptional fromComponent (Component parentComponent) { + + Window owner = findOwnerByComponent(parentComponent); + + IdePopupManager manager = IdeEventQueue.getInstance().getPopupManager(); + + if (manager.isPopupWindow(owner)) { + + manager.closeAllPopups(); + + owner = owner.getOwner(); + + while (owner != null + && !(owner instanceof Dialog) + && !(owner instanceof Frame)) { + owner = owner.getOwner(); + } + } + + if (owner instanceof Dialog) { + Dialog ownerDialog = (Dialog)owner; + if (ownerDialog.isModal()) { + owner = ownerDialog; + } + else { + while (owner instanceof Dialog && !((Dialog)owner).isModal()) { + owner = owner.getOwner(); + } + } + } + + return new OwnerOptional(owner); + } + + public OwnerOptional ifDialog(Consumer consumer) { + if (myPermanentOwner instanceof Dialog) { + consumer.consume((Dialog)myPermanentOwner); + } + return this; + } + + public OwnerOptional ifNull(Consumer consumer) { + consumer.consume((Frame)this.myPermanentOwner); + return this; + } + + public OwnerOptional ifFrame(Consumer consumer) { + if (myPermanentOwner instanceof Frame) { + if (myPermanentOwner instanceof IdeFrame.Child) { + IdeFrame.Child ideFrameChild = (IdeFrame.Child)myPermanentOwner; + myPermanentOwner = WindowManager.getInstance().getFrame(ideFrameChild.getProject()); + } + consumer.consume((Frame)this.myPermanentOwner); + } + return this; + } + + public Window get() { + return myPermanentOwner; + } +}