diff --git a/platform/platform-impl/src/com/intellij/ide/actions/EditSourceInNewWindowAction.java b/platform/platform-impl/src/com/intellij/ide/actions/EditSourceInNewWindowAction.java new file mode 100644 index 000000000000..2190622fd27a --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/actions/EditSourceInNewWindowAction.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2013 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.ide.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author Konstantin Bulenkov + */ +public class EditSourceInNewWindowAction extends DumbAwareAction { + @Override + public void actionPerformed(AnActionEvent e) { + final FileEditorManager manager = FileEditorManager.getInstance(getEventProject(e)); + ((FileEditorManagerImpl)manager).openFileInNewWindow(getVirtualFiles(e)[0]); + } + + protected VirtualFile[] getVirtualFiles(AnActionEvent e) { + final VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); + if (files != null) return files; + + final VirtualFile file = e.getData(PlatformDataKeys.VIRTUAL_FILE); + return file == null ? VirtualFile.EMPTY_ARRAY : new VirtualFile[]{file}; + } + + @Override + public void update(AnActionEvent e) { + e.getPresentation().setEnabledAndVisible(getEventProject(e) != null && getVirtualFiles(e).length == 1); + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/DockableEditorTabbedContainer.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/DockableEditorTabbedContainer.java index 3620370637cc..e48da04150f3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/DockableEditorTabbedContainer.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/DockableEditorTabbedContainer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -100,7 +100,7 @@ public class DockableEditorTabbedContainer implements DockContainer.Persistent { @Nullable private JBTabs getTabsAt(DockableContent content, RelativePoint point) { - if (content instanceof EditorTabbedContainer.MyDragOutDelegate.DockableEditor) { + if (content instanceof EditorTabbedContainer.DockableEditor) { JBTabs targetTabs = mySplitters.getTabsAt(point); if (targetTabs != null) { return targetTabs; @@ -135,7 +135,7 @@ public class DockableEditorTabbedContainer implements DockContainer.Persistent { } } - final EditorTabbedContainer.MyDragOutDelegate.DockableEditor dockableEditor = (EditorTabbedContainer.MyDragOutDelegate.DockableEditor)content; + final EditorTabbedContainer.DockableEditor dockableEditor = (EditorTabbedContainer.DockableEditor)content; VirtualFile file = dockableEditor.getFile(); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java index 419f3063361c..cb260c8fa1cb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -71,7 +71,7 @@ import java.util.Map; * @author Anton Katilin * @author Vladimir Kondratyev */ -final class EditorTabbedContainer implements Disposable, CloseAction.CloseTarget { +public final class EditorTabbedContainer implements Disposable, CloseAction.CloseTarget { private final EditorWindow myWindow; private final Project myProject; private final JBEditorTabs myTabs; @@ -162,6 +162,11 @@ final class EditorTabbedContainer implements Disposable, CloseAction.CloseTarget return myTabs.select(myTabs.getTabAt(indexToSelect), focusEditor); } + + public static DockableEditor createDockableEditor(Project project, Image image, VirtualFile file, Presentation presentation, EditorWindow window) { + return new DockableEditor(project, image, file, presentation, window); + } + private void updateTabBorder() { if (!myProject.isOpen()) return; @@ -582,7 +587,7 @@ final class EditorTabbedContainer implements Disposable, CloseAction.CloseTarget myFile = (VirtualFile)info.getObject(); Presentation presentation = new Presentation(info.getText()); presentation.setIcon(info.getIcon()); - mySession = getDockManager().createDragSession(mouseEvent, new DockableEditor(img, myFile, presentation, myWindow)); + mySession = getDockManager().createDragSession(mouseEvent, createDockableEditor(myProject, img, myFile, presentation, myWindow)); } private DockManager getDockManager() { @@ -625,63 +630,64 @@ final class EditorTabbedContainer implements Disposable, CloseAction.CloseTarget mySession = null; } - class DockableEditor implements DockableContent { - final Image myImg; - private DockableEditorTabbedContainer myContainer; - private Presentation myPresentation; - private EditorWindow myEditorWindow; - private Dimension myPreferredSize; - private boolean myPinned; + } + public static class DockableEditor implements DockableContent { + final Image myImg; + private DockableEditorTabbedContainer myContainer; + private Presentation myPresentation; + private EditorWindow myEditorWindow; + private Dimension myPreferredSize; + private boolean myPinned; + private VirtualFile myFile; - public DockableEditor(Image img, VirtualFile file, Presentation presentation, EditorWindow window) { - myImg = img; - myFile = file; - myPresentation = presentation; - myContainer = new DockableEditorTabbedContainer(myProject); - myEditorWindow = window; - myPreferredSize = myEditorWindow.getSize(); - myPinned = window.isFilePinned(file); - } + public DockableEditor(Project project, Image img, VirtualFile file, Presentation presentation, EditorWindow window) { + myImg = img; + myFile = file; + myPresentation = presentation; + myContainer = new DockableEditorTabbedContainer(project); + myEditorWindow = window; + myPreferredSize = myEditorWindow.getSize(); + myPinned = window.isFilePinned(file); + } - @NotNull - @Override - public VirtualFile getKey() { - return myFile; - } + @NotNull + @Override + public VirtualFile getKey() { + return myFile; + } - @Override - public Image getPreviewImage() { - return myImg; - } + @Override + public Image getPreviewImage() { + return myImg; + } - @Override - public Dimension getPreferredSize() { - return myPreferredSize; - } + @Override + public Dimension getPreferredSize() { + return myPreferredSize; + } - @Override - public String getDockContainerType() { - return DockableEditorContainerFactory.TYPE; - } + @Override + public String getDockContainerType() { + return DockableEditorContainerFactory.TYPE; + } - @Override - public Presentation getPresentation() { - return myPresentation; - } + @Override + public Presentation getPresentation() { + return myPresentation; + } - @Override - public void close() { - myContainer.close(myFile); - } + @Override + public void close() { + myContainer.close(myFile); + } - public VirtualFile getFile() { - return myFile; - } + public VirtualFile getFile() { + return myFile; + } - public boolean isPinned() { - return myPinned; - } + public boolean isPinned() { + return myPinned; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java index ed39011cc635..8dcd72f22b7e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -68,6 +68,7 @@ import com.intellij.ui.FocusTrackback; import com.intellij.ui.Gray; import com.intellij.ui.docking.DockContainer; import com.intellij.ui.docking.DockManager; +import com.intellij.ui.docking.impl.DockManagerImpl; import com.intellij.ui.tabs.impl.JBTabsImpl; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.messages.MessageBusConnection; @@ -83,6 +84,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.Border; import java.awt.*; +import java.awt.event.KeyEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.ref.WeakReference; @@ -598,6 +600,11 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec } assertDispatchThread(); + if (isShiftEnter(EventQueue.getCurrentEvent())) { + return openFileInNewWindow(file); + } + + EditorWindow wndToOpenIn = null; if (searchForSplitter) { Set all = getAllSplitters(); @@ -630,6 +637,16 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec return openFileImpl2(wndToOpenIn, file, focusEditor); } + public Pair openFileInNewWindow(VirtualFile file) { + return ((DockManagerImpl)DockManager.getInstance(getProject())).createNewDockContainerFor(file, this); + } + + private static boolean isShiftEnter(AWTEvent event) { + return event instanceof KeyEvent + && ((KeyEvent)event).getKeyCode() == KeyEvent.VK_ENTER + && ((KeyEvent)event).isShiftDown(); + } + private void openAssociatedFile(VirtualFile file, EditorWindow wndToOpenIn, EditorsSplitters splitters) { EditorWindow[] windows = splitters.getWindows(); diff --git a/platform/platform-impl/src/com/intellij/ui/docking/impl/DockManagerImpl.java b/platform/platform-impl/src/com/intellij/ui/docking/impl/DockManagerImpl.java index 76e906610ed6..7e7563975498 100644 --- a/platform/platform-impl/src/com/intellij/ui/docking/impl/DockManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/docking/impl/DockManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -19,16 +19,19 @@ import com.intellij.ide.IdeEventQueue; import com.intellij.ide.ui.UISettings; import com.intellij.ide.ui.UISettingsListener; import com.intellij.openapi.Disposable; +import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.components.StoragePathMacros; -import com.intellij.openapi.extensions.ExtensionPointListener; import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.extensions.PluginDescriptor; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorProvider; +import com.intellij.openapi.fileEditor.impl.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.FrameWrapper; import com.intellij.openapi.util.*; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.IdeFrame; import com.intellij.openapi.wm.IdeRootPaneNorthExtension; @@ -405,6 +408,46 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo } }); } + public Pair createNewDockContainerFor(VirtualFile file, FileEditorManagerImpl fileEditorManager) { + DockContainer container = getFactory(DockableEditorContainerFactory.TYPE).createContainer(null); + register(container); + + final DockWindow window = createWindowFor(null, container); + Point showPoint = DimensionService.getInstance().getLocation("new.editor.frame", myProject); + Dimension size = DimensionService.getInstance().getSize("new.editor.frame", myProject); + + if (size == null) { + final IdeFrame frame = WindowManagerEx.getInstanceEx().findFrameFor(myProject); + size = new Dimension(((Window)frame).getWidth() - 200, ((Window)frame).getHeight() - 200); + } + if (showPoint == null) { + final IdeFrame frame = WindowManagerEx.getInstanceEx().findFrameFor(myProject); + showPoint = new Point(((Window)frame).getX() + 100, ((Window)frame).getY() + 100); + } + + Rectangle target = new Rectangle(showPoint, size); + ScreenUtil.moveRectangleToFitTheScreen(target); + ScreenUtil.cropRectangleToFitTheScreen(target); + + window.setLocation(target.getLocation()); + window.myDockContentUiContainer.setPreferredSize(target.getSize()); + window.setDimensionKey("new.editor.frame"); + + window.show(false); + window.getFrame().pack(); + final EditorWindow editorWindow = ((DockableEditorTabbedContainer)container).getSplitters().getOrCreateCurrentWindow(file); + final Pair result = fileEditorManager.openFileImpl2(editorWindow, file, true); + container.add(EditorTabbedContainer.createDockableEditor(myProject, null, file, new Presentation(file.getName()), + editorWindow), new RelativePoint(target.getLocation())); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + window.myUiContainer.setPreferredSize(null); + } + }); + return result; + } private DockWindow createWindowFor(@Nullable String id, DockContainer container) { String windowId = id != null ? id : String.valueOf(myWindowIdCounter++); diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 4ca38277c138..f00453bde6fc 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -374,6 +374,8 @@ action.ProjectViewChangeView.text=Change View... action.ProjectViewChangeView.description=Choose Project, Sourcepath or Classpath tree in the Project View window action.EditSource.text=_Jump to Source action.EditSource.description=Open editor for the selected item and give focus to it +action.EditSourceInNewWindow.text=Open source in new window +action.EditSourceInNewWindow.description=Open editor for the selected item in new window and give focus to it action.ViewSource.text=Sho_w Source action.ViewSource.description=Open editor for the selected item action.ExternalJavaDoc.text=E_xternal Documentation diff --git a/platform/platform-resources/src/idea/Keymap_Default.xml b/platform/platform-resources/src/idea/Keymap_Default.xml index 078af9e7a77b..9394a0e32f96 100644 --- a/platform/platform-resources/src/idea/Keymap_Default.xml +++ b/platform/platform-resources/src/idea/Keymap_Default.xml @@ -568,6 +568,9 @@ + + + diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 8e28866986f5..57ce347c1314 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -20,6 +20,7 @@ +