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);
+ }
+}