From 4b2204574dbeb0b9364d0888d7e9b5e7e78f48e2 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Sun, 10 Nov 2013 18:03:51 +0100 Subject: [PATCH] Terminal tabs: drag'n'drop to editor and back implemented. --- .../util/remote-servers-util.iml | 21 +++ .../terminal/resources/META-INF/terminal.xml | 2 + .../terminal/JBTabbedTerminalWidget.java | 84 +++++++++++- .../plugins/terminal/TerminalView.java | 103 +++++++++++++- .../terminal/vfs/TerminalSessionEditor.java | 127 +++++++++++++++++ .../vfs/TerminalSessionEditorProvider.java | 71 ++++++++++ .../terminal/vfs/TerminalSessionFileType.java | 42 ++++++ .../vfs/TerminalSessionVirtualFileImpl.java | 49 +++++++ .../terminal/vfs/TerminalSessionsVFS.java | 128 ++++++++++++++++++ 9 files changed, 623 insertions(+), 4 deletions(-) create mode 100644 platform/remote-servers/util/remote-servers-util.iml create mode 100644 plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditor.java create mode 100644 plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditorProvider.java create mode 100644 plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionFileType.java create mode 100644 plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionVirtualFileImpl.java create mode 100644 plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionsVFS.java diff --git a/platform/remote-servers/util/remote-servers-util.iml b/platform/remote-servers/util/remote-servers-util.iml new file mode 100644 index 000000000000..e3c631600634 --- /dev/null +++ b/platform/remote-servers/util/remote-servers-util.iml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/terminal/resources/META-INF/terminal.xml b/plugins/terminal/resources/META-INF/terminal.xml index 36500b84045e..ed2a2b56ec64 100644 --- a/plugins/terminal/resources/META-INF/terminal.xml +++ b/plugins/terminal/resources/META-INF/terminal.xml @@ -12,6 +12,8 @@ factoryClass="org.jetbrains.plugins.terminal.TerminalToolWindowFactory" secondary="false"/> + + diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java index f5d3eb9597b6..be22ab8ffbd7 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java @@ -5,11 +5,17 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.fileEditor.impl.EditorTabbedContainer; +import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.components.JBTextField; +import com.intellij.ui.docking.DockContainer; +import com.intellij.ui.docking.DockManager; +import com.intellij.ui.docking.DragSession; import com.intellij.ui.tabs.TabInfo; import com.intellij.ui.tabs.TabsListener; import com.intellij.ui.tabs.impl.JBEditorTabs; @@ -19,6 +25,7 @@ import com.jediterm.terminal.ui.*; import com.jediterm.terminal.ui.settings.SettingsProvider; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.terminal.vfs.TerminalSessionVirtualFileImpl; import javax.swing.*; import javax.swing.event.ChangeEvent; @@ -86,6 +93,8 @@ public class JBTabbedTerminalWidget extends TabbedTerminalWidget { public class JBTerminalTabs implements TerminalTabs { private final JBEditorTabs myTabs; + private TabInfo.DragOutDelegate myDragDelegate = new MyDragOutDelegate(); + private final CopyOnWriteArraySet myListeners = new CopyOnWriteArraySet(); public JBTerminalTabs(@NotNull Project project, @NotNull Disposable parent) { @@ -170,7 +179,7 @@ public class JBTabbedTerminalWidget extends TabbedTerminalWidget { } @Override - public Component getComponent() { + public JComponent getComponent() { return myTabs.getComponent(); } @@ -181,7 +190,12 @@ public class JBTabbedTerminalWidget extends TabbedTerminalWidget { @Override public void addTab(String name, JediTermWidget terminal) { - myTabs.addTab(new TabInfo(terminal).setText(name)); + myTabs.addTab(createTabInfo(name, terminal)); + } + + private TabInfo createTabInfo(String name, JediTermWidget terminal) { + return new TabInfo(terminal).setText(name).setDragOutDelegate(myDragDelegate) + .setObject(new TerminalSessionVirtualFileImpl(name, terminal)); } public String getTitleAt(int i) { @@ -289,7 +303,7 @@ public class JBTabbedTerminalWidget extends TabbedTerminalWidget { @Override public void setComponent(Component c) { myTabs.setTabDraggingEnabled(!(c instanceof JBTextField)); - + setPlaceholderContent(true, (JComponent)c); } @@ -300,5 +314,69 @@ public class JBTabbedTerminalWidget extends TabbedTerminalWidget { }); } } + + class MyDragOutDelegate implements TabInfo.DragOutDelegate { + + private TerminalSessionVirtualFileImpl myFile; + private DragSession mySession; + + @Override + public void dragOutStarted(MouseEvent mouseEvent, TabInfo info) { + final TabInfo previousSelection = info.getPreviousSelection(); + final Image img = JBTabsImpl.getComponentImage(info); + info.setHidden(true); + if (previousSelection != null) { + myTabs.select(previousSelection, true); + } + + myFile = (TerminalSessionVirtualFileImpl)info.getObject(); + Presentation presentation = new Presentation(info.getText()); + presentation.setIcon(info.getIcon()); + mySession = getDockManager() + .createDragSession(mouseEvent, new EditorTabbedContainer.DockableEditor(myProject, img, myFile, presentation, + info.getComponent().getPreferredSize(), false)); + } + + private DockManager getDockManager() { + return DockManager.getInstance(myProject); + } + + @Override + public void processDragOut(MouseEvent event, TabInfo source) { + mySession.process(event); + } + + @Override + public void dragOutFinished(MouseEvent event, TabInfo source) { + boolean copy = + com.intellij.util.ui.UIUtil.isControlKeyDown(event) || mySession.getResponse(event) == DockContainer.ContentResponse.ACCEPT_COPY; + if (!copy) { + myFile.putUserData(FileEditorManagerImpl.CLOSING_TO_REOPEN, Boolean.TRUE); + // FileEditorManagerEx.getInstanceEx(myProject).closeFile(myFile, myWindow); TODO + } + else { + source.setHidden(false); + } + + mySession.process(event); + if (!copy) { + myFile.putUserData(FileEditorManagerImpl.CLOSING_TO_REOPEN, null); + } + + myFile = null; + mySession = null; + } + + @Override + public void dragOutCancelled(TabInfo source) { + source.setHidden(false); + if (mySession != null) { + mySession.cancel(); + } + + myFile = null; + mySession = null; + } + } } } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java index 2821a98a22dd..b6c39711d8b1 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java @@ -12,8 +12,13 @@ import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.openapi.wm.ex.ToolWindowManagerEx; import com.intellij.openapi.wm.ex.ToolWindowManagerListener; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.awt.RelativeRectangle; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; +import com.intellij.ui.docking.DockContainer; +import com.intellij.ui.docking.DockManager; +import com.intellij.ui.docking.DockableContent; import com.intellij.util.ui.UIUtil; import com.jediterm.terminal.ui.JediTermWidget; import com.jediterm.terminal.ui.TabbedTerminalWidget; @@ -21,8 +26,10 @@ import com.jediterm.terminal.ui.TerminalWidget; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.terminal.vfs.TerminalSessionVirtualFileImpl; import javax.swing.*; +import java.awt.*; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; @@ -35,6 +42,8 @@ public class TerminalView { private final Project myProject; + private TerminalDockContainer myDockContainer; + public TerminalView(Project project) { myProject = project; } @@ -81,6 +90,12 @@ public class TerminalView { } }); } + + if (myDockContainer == null) { + myDockContainer = new TerminalDockContainer(toolWindow); + + DockManager.getInstance(myProject).register(myDockContainer); + } } private Content createTerminalInContentPanel(@Nullable LocalTerminalDirectRunner terminalRunner, @@ -118,7 +133,6 @@ public class TerminalView { toolbar.setTargetComponent(panel); panel.setToolbar(toolbar.getComponent()); - content.setPreferredFocusableComponent(myTerminalWidget.getComponent()); @@ -232,4 +246,91 @@ public class TerminalView { hideIfNoActiveSessions(myToolWindow, myTerminal); } } + + /** + * @author traff + */ + public class TerminalDockContainer implements DockContainer { + private ToolWindow myTerminalToolWindow; + + public TerminalDockContainer(ToolWindow toolWindow) { + myTerminalToolWindow = toolWindow; + } + + @Override + public RelativeRectangle getAcceptArea() { + return new RelativeRectangle(myTerminalToolWindow.getComponent()); + } + + @NotNull + @Override + public ContentResponse getContentResponse(@NotNull DockableContent content, RelativePoint point) { + return ContentResponse.ACCEPT_MOVE; + } + + @Override + public JComponent getContainerComponent() { + return myTerminalToolWindow.getComponent(); + } + + @Override + public void add(@NotNull DockableContent content, RelativePoint dropTarget) { + if (content.getKey() instanceof TerminalSessionVirtualFileImpl) { + TerminalSessionVirtualFileImpl terminalFile = (TerminalSessionVirtualFileImpl)content.getKey(); + myTerminalWidget.addTab(terminalFile.getName(), terminalFile.getTerminal()); + } + } + + @Override + public void closeAll() { + + } + + @Override + public void addListener(Listener listener, Disposable parent) { + + } + + @Override + public boolean isEmpty() { + return false; + } + + @Nullable + @Override + public Image startDropOver(@NotNull DockableContent content, RelativePoint point) { + return null; + } + + @Nullable + @Override + public Image processDropOver(@NotNull DockableContent content, RelativePoint point) { + return null; + } + + @Override + public void resetDropOver(@NotNull DockableContent content) { + + } + + @Override + public boolean isDisposeWhenEmpty() { + return false; + } + + @Override + public void showNotify() { + + } + + @Override + public void hideNotify() { + + } + + @Override + public void dispose() { + + } + } } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditor.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditor.java new file mode 100644 index 000000000000..c1b4b5556867 --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditor.java @@ -0,0 +1,127 @@ +/* + * 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 org.jetbrains.plugins.terminal.vfs; + +import com.intellij.codeHighlighting.BackgroundEditorHighlighter; +import com.intellij.ide.structureView.StructureViewBuilder; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorLocation; +import com.intellij.openapi.fileEditor.FileEditorState; +import com.intellij.openapi.fileEditor.FileEditorStateLevel; +import com.intellij.openapi.util.UserDataHolderBase; +import com.jediterm.terminal.ui.JediTermWidget; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.beans.PropertyChangeListener; + +/** + * @author traff + */ +public class TerminalSessionEditor extends UserDataHolderBase implements FileEditor { + + private final JediTermWidget myTerminal; + private final String myName; + + public TerminalSessionEditor(@NotNull TerminalSessionVirtualFileImpl terminalFile) { + myTerminal = terminalFile.getTerminal(); + myName = terminalFile.getName(); + } + + + @NotNull + @Override + public JComponent getComponent() { + return myTerminal; + } + + @Nullable + @Override + public JComponent getPreferredFocusedComponent() { + return myTerminal; + } + + @NotNull + @Override + public String getName() { + return myName; + } + + @NotNull + @Override + public FileEditorState getState(@NotNull FileEditorStateLevel level) { + return FileEditorState.INSTANCE; + } + + @Override + public void setState(@NotNull FileEditorState state) { + + } + + @Override + public boolean isModified() { + return false; + } + + @Override + public boolean isValid() { + return true; + } + + @Override + public void selectNotify() { + + } + + @Override + public void deselectNotify() { + + } + + @Override + public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) { + + } + + @Override + public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) { + + } + + @Nullable + @Override + public BackgroundEditorHighlighter getBackgroundHighlighter() { + return null; + } + + @Nullable + @Override + public FileEditorLocation getCurrentLocation() { + return null; + } + + @Nullable + @Override + public StructureViewBuilder getStructureViewBuilder() { + return null; + } + + @Override + public void dispose() { + myTerminal.close(); + } +} diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditorProvider.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditorProvider.java new file mode 100644 index 000000000000..c3201c08a7d4 --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditorProvider.java @@ -0,0 +1,71 @@ +/* + * 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 org.jetbrains.plugins.terminal.vfs; + +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorPolicy; +import com.intellij.openapi.fileEditor.FileEditorProvider; +import com.intellij.openapi.fileEditor.FileEditorState; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.vfs.VirtualFile; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; + +/** + * @author traff + */ +public class TerminalSessionEditorProvider implements FileEditorProvider, DumbAware { + @Override + public boolean accept(@NotNull Project project, @NotNull VirtualFile file) { + return file instanceof TerminalSessionVirtualFileImpl; + } + + @NotNull + @Override + public FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile file) { + return new TerminalSessionEditor((TerminalSessionVirtualFileImpl)file); + } + + @Override + public void disposeEditor(@NotNull FileEditor editor) { + Disposer.dispose(editor); + } + + @NotNull + @Override + public FileEditorState readState(@NotNull Element sourceElement, @NotNull Project project, @NotNull VirtualFile file) { + return FileEditorState.INSTANCE; + } + + @Override + public void writeState(@NotNull FileEditorState state, @NotNull Project project, @NotNull Element targetElement) { + + } + + @NotNull + @Override + public String getEditorTypeId() { + return "terminal-session-editor"; + } + + @NotNull + @Override + public FileEditorPolicy getPolicy() { + return FileEditorPolicy.HIDE_DEFAULT_EDITOR; + } +} diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionFileType.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionFileType.java new file mode 100644 index 000000000000..bb545a18504c --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionFileType.java @@ -0,0 +1,42 @@ +/* + * 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 org.jetbrains.plugins.terminal.vfs; + +import com.intellij.openapi.fileTypes.ex.FakeFileType; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +/** + * @author traff + */ +public class TerminalSessionFileType extends FakeFileType { + + public final static TerminalSessionFileType INSTANCE = new TerminalSessionFileType(); + + @NotNull + public String getName() { + return "Terminal Session"; + } + + @NotNull + public String getDescription() { + return getName() + " Fake File Type"; + } + + public boolean isMyFileType(VirtualFile file) { + return file instanceof TerminalSessionVirtualFileImpl; + } +} diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionVirtualFileImpl.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionVirtualFileImpl.java new file mode 100644 index 000000000000..3f29a182b9e2 --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionVirtualFileImpl.java @@ -0,0 +1,49 @@ +/* + * 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. + */ + +/** + * @author cdr + */ +package org.jetbrains.plugins.terminal.vfs; + +import com.intellij.testFramework.LightVirtualFile; +import com.jediterm.terminal.ui.JediTermWidget; +import org.jetbrains.annotations.NotNull; + +/** + * @author traff + */ +public class TerminalSessionVirtualFileImpl extends LightVirtualFile { + private final JediTermWidget myTerminal; + + private final String myName; + + public TerminalSessionVirtualFileImpl(String name, JediTermWidget terminal) { + myName = name; + myTerminal = terminal; + setFileType(TerminalSessionFileType.INSTANCE); + setWritable(true); + } + + public JediTermWidget getTerminal() { + return myTerminal; + } + + @NotNull + public String getName() { + return myName; + } +} diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionsVFS.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionsVFS.java new file mode 100644 index 000000000000..b1439ccd069c --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionsVFS.java @@ -0,0 +1,128 @@ +/* + * 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 org.jetbrains.plugins.terminal.vfs; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerAdapter; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.ex.dummy.DummyFileSystem; +import com.intellij.util.containers.BidirectionalMap; +import com.intellij.util.containers.HashMap; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.Map; + +/** + * @author traff + */ +public class TerminalSessionsVFS extends DummyFileSystem { + @NonNls private static final String PROTOCOL = "terminalDummy"; + @NonNls private static final String PATH_PREFIX = "terminal"; + @NonNls private static final String PROTOCOL_SEPARATOR = ":/"; + + private final BidirectionalMap myProject2Id = new BidirectionalMap(); + private final Map myCachedFiles = new HashMap(); + + private ProjectManagerAdapter myProjectManagerListener; + + public static TerminalSessionsVFS getTerminalSessionVFS() { + return (TerminalSessionsVFS)VirtualFileManager.getInstance().getFileSystem(PROTOCOL); + } + + @Override + @Nullable + public VirtualFile createRoot(String name) { + return null; + } + + public void initListener() { + if (myProjectManagerListener == null || ApplicationManager.getApplication().isUnitTestMode()) { + myCachedFiles.clear(); + myProject2Id.clear(); + for (Project project : ProjectManager.getInstance().getOpenProjects()) { + onProjectOpened(project); + } + } + if (myProjectManagerListener == null) { + myProjectManagerListener = new ProjectManagerAdapter() { + @Override + public void projectOpened(final Project project) { + onProjectOpened(project); + } + + @Override + public void projectClosed(final Project project) { + onProjectClosed(project); + } + }; + ProjectManager.getInstance().addProjectManagerListener(myProjectManagerListener); + } + } + + public void onProjectClosed(final Project project) { + myCachedFiles.clear(); + myProject2Id.remove(project); + } + + public void onProjectOpened(final Project project) { + myProject2Id.put(project, project.getLocationHash()); + StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { + @Override + public void run() { +// DatabaseEditorHelper.installEditorFactoryListener(project); TODO:? + } + }); + } + + @Override + public VirtualFile findFileByPath(@NotNull String path) { + throw new UnsupportedOperationException("not implemented yet"); //TODO: implement TerminalSessionManager and store there terminal sessions by handle ID + } + + public static String getPath(Project project, final String dataSourceId, final String tableName, String typeName) { + return PATH_PREFIX + typeName + PROTOCOL_SEPARATOR + project.getLocationHash() + "/" + dataSourceId + "/" + tableName; + } + + @Override + @NotNull + public String getProtocol() { + return PROTOCOL; + } + + @Override + public boolean isReadOnly() { + return false; + } + + @Override + public void renameFile(Object requestor, @NotNull VirtualFile vFile, @NotNull String newName) throws IOException { + throw new UnsupportedOperationException("renameFile not supported"); + } + + @Override + @NotNull + public String extractPresentableUrl(@NotNull String path) { + VirtualFile file = findFileByPath(path); + return file != null ? file.getPresentableName() : super.extractPresentableUrl(path); + } +}