diff options
Diffstat (limited to 'platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java')
-rw-r--r-- | platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java | 403 |
1 files changed, 275 insertions, 128 deletions
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java index a9634d5a335a..999fe75523e9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java @@ -17,162 +17,276 @@ package com.intellij.openapi.fileEditor.impl; import com.intellij.icons.AllIcons; import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.UISettingsListener; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.event.DocumentEvent; -import com.intellij.openapi.editor.event.DocumentListener; -import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.ToggleAction; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.FileEditorManagerListener; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.wm.ToolWindowAnchor; -import com.intellij.openapi.wm.ToolWindowId; -import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.*; import com.intellij.openapi.wm.impl.ToolWindowImpl; -import com.intellij.ui.JBColor; +import com.intellij.openapi.wm.impl.content.ToolWindowContentUi; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; +import com.intellij.ui.content.ContentManagerAdapter; +import com.intellij.ui.content.ContentManagerEvent; import com.intellij.ui.docking.DockManager; +import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.util.ArrayList; +import java.util.EnumSet; -class PreviewPanel extends JPanel implements DocumentListener, FileEditorManagerListener.Before { +class PreviewPanel extends JPanel { + + private CardLayout myLayout; + + enum ContentType {Files, Usages, Diagrams, Documentation} + + private static final Key<VirtualFile> FILE_KEY = Key.create("v_file"); private static final int HISTORY_LIMIT = 10; private final Project myProject; private final FileEditorManagerImpl myManager; private final DockManager myDockManager; private EditorWindow myWindow; - private boolean myInitialized = false; private EditorsSplitters myEditorsSplitters; private ArrayList<VirtualFile> myHistory = new ArrayList<VirtualFile>(); private VirtualFile myModifiedFile = null; private ToolWindowImpl myToolWindow; private VirtualFile myAwaitingForOpen = null; + private ContentManager myContentManager; + private Content myStubContent; + private boolean myBlocked = false; + + private EnumSet<ContentType> myTypes = EnumSet.noneOf(ContentType.class); + + static boolean isAvailable() { + return UISettings.getInstance().NAVIGATE_TO_PREVIEW; + } - public PreviewPanel(Project project, FileEditorManagerImpl manager, DockManager dockManager) { + PreviewPanel(Project project, FileEditorManagerImpl manager, DockManager dockManager) { myProject = project; myManager = manager; myDockManager = dockManager; - setOpaque(true); - setBackground(JBColor.DARK_GRAY); + } + + /* + * @return null if preview is not avalable + */ + @Nullable + EditorWindow getWindow() { + if (!isAvailable() || isBlocked() || myProject.isDisposed()) return null; + initToolWindowIfNeed(); + return myWindow; + } + + boolean isBlocked() { + return myBlocked; } private void initToolWindowIfNeed() { - if (myInitialized) return; + if (!isAvailable() || ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW) != null) return; myToolWindow = (ToolWindowImpl)ToolWindowManager.getInstance(myProject) .registerToolWindow(ToolWindowId.PREVIEW, this, ToolWindowAnchor.RIGHT, myProject, false); - myToolWindow.setIcon(AllIcons.Actions.PreviewDetails); - - myEditorsSplitters = new EditorsSplitters(myManager, myDockManager, false) { + UISettings.getInstance().addUISettingsListener(new UISettingsListener() { @Override - public void updateFileName(VirtualFile updatedFile) { - super.updateFileName(updatedFile); - if (updatedFile != null && updatedFile.equals(getCurrentFile())) { - updateWindowTitle(updatedFile); - } - } - - @Override - protected void afterFileOpen(VirtualFile file) { - if (file.equals(myAwaitingForOpen)) { - updateWindowTitle(file); - Document document = FileDocumentManager.getInstance().getDocument(file); - if (document != null) { - myModifiedFile = null; - document.addDocumentListener(PreviewPanel.this, myProject); + public void uiSettingsChanged(UISettings source) { + if (!isAvailable()) { + VirtualFile[] files = myWindow.getFiles(); + for (VirtualFile file : files) { + close(file); } + ToolWindowManager.getInstance(myProject).unregisterToolWindow(ToolWindowId.PREVIEW); } - myAwaitingForOpen = null; } - + }, myProject); + myToolWindow.setIcon(AllIcons.Actions.PreviewDetails); + myToolWindow.setContentUiType(ToolWindowContentUiType.COMBO, null); + myContentManager = myToolWindow.getContentManager(); + myStubContent = myContentManager.getContent(0); + myContentManager.addContentManagerListener(new ContentManagerAdapter() { @Override - public void setTabsPlacement(int tabPlacement) { - super.setTabsPlacement(UISettings.TABS_NONE); - } + public void selectionChanged(ContentManagerEvent event) { + final VirtualFile file = event.getContent().getUserData(FILE_KEY); + if (event.getOperation() == ContentManagerEvent.ContentOperation.remove && file != null && file.equals(myModifiedFile)) { + close(file); + return; + } - @Override - protected boolean showEmptyText() { - return false; + if (event.getOperation() != ContentManagerEvent.ContentOperation.add) return; + + if (file != null) { + event.getContent().setComponent(PreviewPanel.this);//Actually we share the same component between contents + if (!file.equals(myWindow.getSelectedFile())) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + myManager.openFileWithProviders(file, false, myWindow); + } + }); + } + } } - }; - - myProject.getMessageBus().connect().subscribe(FileEditorManagerListener.Before.FILE_EDITOR_MANAGER, this); + }); + + myEditorsSplitters = new MyEditorsSplitters(); + + myProject.getMessageBus().connect().subscribe(FileEditorManagerListener.Before.FILE_EDITOR_MANAGER, + new FileEditorManagerListener.Before() { + @Override + public void beforeFileOpened(@NotNull FileEditorManager source, + @NotNull VirtualFile file) { + myAwaitingForOpen = file; + VirtualFile currentFile = getCurrentFile(); + if (currentFile != null && + currentFile.equals(myModifiedFile) && + !currentFile.equals(file)) { + close(currentFile); + } + } + + @Override + public void beforeFileClosed(@NotNull FileEditorManager source, + @NotNull VirtualFile file) { + checkStubContent(); + } + }); myEditorsSplitters.createCurrentWindow(); - myWindow = myEditorsSplitters.getCurrentWindow(); myWindow.setTabsPlacement(UISettings.TABS_NONE); + myLayout = new CardLayout(); + setLayout(myLayout); + add(ContentType.Files.toString(), myEditorsSplitters); + //add(ContentType.Usages.toString(), myUsagesPreview);??? tree or editor ??? + //add(ContentType.Diagrams.toString(), myDiagramPanel); + //add(ContentType.Documentation.toString(), myDocumentationPanel);//todo + myToolWindow.setTitleActions(new MoveToEditorTabsAction()); + ArrayList<AnAction> myGearActions = new ArrayList<AnAction>(); + for (ContentType contentType : ContentType.values()) { + myGearActions.add(new ContentTypeToggleAction(contentType)); + } + myToolWindow.setAdditionalGearActions(new DefaultActionGroup("Preview", myGearActions)); + myToolWindow.hide(null); + } - setLayout(new GridLayout(1, 1)); - add(myEditorsSplitters); - - myToolWindow.setTitleActions(new MoveToEditorTabsAction(), new CloseFileAction()); - - myInitialized = true; + @Nullable + private VirtualFile getCurrentFile() { + VirtualFile[] files = myWindow.getFiles(); + return files.length == 1 ? files[0] : null; } - private void updateWindowTitle(VirtualFile file) { - if (myToolWindow == null) return; - if (file == null) { - myToolWindow.setTitle(": (empty)"); - } - else { - myToolWindow.setTitle(": " + - StringUtil.getShortened(EditorTabbedContainer.calcTabTitle(myProject, file), - UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT)); + @NotNull + private Content addContent(VirtualFile file) { + myHistory.add(file); + while (myHistory.size() > HISTORY_LIMIT) { + myHistory.remove(0); } + String title = + StringUtil.getShortened(EditorTabbedContainer.calcTabTitle(myProject, file), UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT); + + Content content = myContentManager.getFactory().createContent(this, title, false); + content.putUserData(ToolWindow.SHOW_CONTENT_ICON, Boolean.TRUE); + content.putUserData(FILE_KEY, file); + content.setIcon(file.getFileType().getIcon()); + content.setPopupIcon(file.getFileType().getIcon()); + + myContentManager.addContent(content, 0); + checkStubContent(); + return content; } - @Override - public void beforeFileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) { - myAwaitingForOpen = file; + private void setSelected(VirtualFile file) { + Content content = getContent(file); + if (content == null) { + content = addContent(file); + } + myContentManager.setSelectedContent(content); + myContentManager.addContent(content, 0); } - @Override - public void beforeFileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) { - if (file.equals(getCurrentFile())) { - updateWindowTitle(null); - Document document = FileDocumentManager.getInstance().getDocument(file); - if (document != null) { - document.removeDocumentListener(this); + @Nullable + private Content getContent(VirtualFile file) { + Content[] contents = myContentManager.getContents(); + for (Content content : contents) { + if (file.equals(content.getUserData(FILE_KEY))) { + return content; } } + return null; } - - @Override - public void beforeDocumentChange(DocumentEvent event) { - - } - - @Override - public void documentChanged(DocumentEvent event) { - VirtualFile file = FileDocumentManager.getInstance().getFile(event.getDocument()); - if (file != null) { - myModifiedFile = file; + private void checkStubContent() { + if (myContentManager.getContents().length == 0) { + myToolWindow.getComponent().putClientProperty(ToolWindowContentUi.HIDE_ID_LABEL, "false"); + myStubContent.setComponent(this); + myContentManager.addContent(myStubContent); + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + if (myContentManager.getIndexOfContent(myStubContent) != -1) { + toggleToolWindow(false); + } + } + }); + } + else if (myContentManager.getContents().length > 1) { + myToolWindow.getComponent().putClientProperty(ToolWindowContentUi.HIDE_ID_LABEL, "true"); + myContentManager.removeContent(myStubContent, false); } } - EditorWindow getWindow() { - initToolWindowIfNeed(); - return myWindow; + private void close(@NotNull VirtualFile file) { + myHistory.remove(file); + if (ArrayUtil.find(myEditorsSplitters.getOpenFiles(), file) != -1) { + myEditorsSplitters.closeFile(file, false); + } + if (file.equals(myAwaitingForOpen)) { + myAwaitingForOpen = null; + } + if (file.equals(myModifiedFile)) { + myBlocked = true; + try { + myManager.openFileWithProviders(myModifiedFile, false, true); + } + finally { + myBlocked = false; + } + myModifiedFile = null; + } + Content content = getContent(file); + if (content != null) { + myContentManager.removeContent(content, false); + checkStubContent(); + } } - @Nullable - VirtualFile getCurrentFile() { - VirtualFile[] files = myWindow.getFiles(); - return files.length == 1 ? files[0] : null; + private void toggleToolWindow(boolean activate) { + ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW); + if (toolWindow != null) { + if (activate) { + toolWindow.activate(null, false); + } + else { + toolWindow.hide(null); + } + } } private class MoveToEditorTabsAction extends AnAction { + public MoveToEditorTabsAction() { - super(null, "Move to main tabs", AllIcons.Duplicates.SendToTheLeftGrayed); + super("Move to main tabs", "Move to main tabs", AllIcons.Duplicates.SendToTheLeftGrayed); } @Override @@ -182,63 +296,96 @@ class PreviewPanel extends JPanel implements DocumentListener, FileEditorManager return; } - myManager.openFileWithProviders(virtualFile, false, myManager.getCurrentWindow()); - closeCurrentFile(); + EditorWindow window = myManager.getCurrentWindow(); + if (window == null) { //main tab set is still not created, rare situation + myManager.getMainSplitters().createCurrentWindow(); + window = myManager.getCurrentWindow(); + } + myManager.openFileWithProviders(virtualFile, true, window); + close(virtualFile); + toggleToolWindow(false); + } + } + + private class ContentTypeToggleAction extends ToggleAction { + private final ContentType myContentType; + + ContentTypeToggleAction(ContentType contentType) { + super(contentType.toString()); + myContentType = contentType; } @Override - public void update(AnActionEvent e) { - super.update(e); - VirtualFile currentFile = getCurrentFile(); - e.getPresentation().setEnabled(currentFile != null); - if (currentFile == null) return; - - if (isModified(currentFile)) { - e.getPresentation().setIcon(AllIcons.Duplicates.SendToTheLeft); - } - else { - e.getPresentation().setIcon(AllIcons.Duplicates.SendToTheLeftGrayed); + public boolean isSelected(AnActionEvent e) { + return myTypes.contains(myContentType); + } + + @Override + public void setSelected(AnActionEvent e, boolean state) { + if (state) { + myTypes.add(myContentType); + } else { + myTypes.remove(myContentType); } } } - private boolean isModified(@NotNull VirtualFile file) { - return file.equals(myModifiedFile); - } + private class MyEditorsSplitters extends EditorsSplitters { + public MyEditorsSplitters() { + super(myManager, myDockManager, false); + } - //returns last open file if it has "modified" status - @Nullable - VirtualFile closeCurrentFile() { - VirtualFile virtualFile = getCurrentFile(); - if (virtualFile == null) return null; - if (!myHistory.contains(virtualFile)) { - myHistory.add(virtualFile); - while (myHistory.size() > HISTORY_LIMIT) { - myHistory.remove(0); + @Override + protected void afterFileOpen(VirtualFile file) { + if (file.equals(myAwaitingForOpen)) { + setSelected(file); } + myAwaitingForOpen = null; + } + + @Override + protected void afterFileClosed(VirtualFile file) { + close(file); } - myWindow.closeFile(virtualFile); - this.revalidate(); - this.repaint(); - return isModified(virtualFile) ? virtualFile : null; - } - private class CloseFileAction extends AnAction { - public CloseFileAction() { - super(null, "Close", AllIcons.Actions.Close); + @Override + public void updateFileIcon(@NotNull VirtualFile file) { + EditorWithProviderComposite composite = myWindow.findFileComposite(file); + if (composite != null && composite.isModified()) { + myModifiedFile = file; + } } @Override - public void actionPerformed(AnActionEvent e) { - if (getCurrentFile() == null) return; - closeCurrentFile(); - ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW).hide(null); + protected EditorWindow createEditorWindow() { + return new EditorWindow(this) { + @Override + protected void onBeforeSetEditor(VirtualFile file) { + VirtualFile currentFile = getCurrentFile(); + if (currentFile != null && currentFile.equals(myModifiedFile)) { + myBlocked = true; + try { + myManager.openFileWithProviders(myModifiedFile, false, true); + } + finally { + myBlocked = false; + } + } + else { + toggleToolWindow(true); + } + } + }; + } + + @Override + public void setTabsPlacement(int tabPlacement) { + super.setTabsPlacement(UISettings.TABS_NONE); } @Override - public void update(AnActionEvent e) { - super.update(e); - e.getPresentation().setEnabled(getCurrentFile() != null); + public boolean isPreview() { + return true; } } } |