| /* |
| * Copyright 2000-2014 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.openapi.fileEditor.impl; |
| |
| import com.intellij.icons.AllIcons; |
| import com.intellij.ide.IdeEventQueue; |
| import com.intellij.ide.actions.CloseAction; |
| import com.intellij.ide.actions.ShowFilePathAction; |
| import com.intellij.ide.ui.UISettings; |
| import com.intellij.ide.ui.UISettingsListener; |
| import com.intellij.ide.ui.customization.CustomActionsSchema; |
| import com.intellij.openapi.Disposable; |
| import com.intellij.openapi.actionSystem.*; |
| import com.intellij.openapi.command.CommandProcessor; |
| import com.intellij.openapi.editor.colors.EditorColorsManager; |
| import com.intellij.openapi.extensions.Extensions; |
| import com.intellij.openapi.fileEditor.FileEditor; |
| import com.intellij.openapi.fileEditor.FileEditorManager; |
| import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; |
| import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; |
| import com.intellij.openapi.project.DumbAware; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.ui.Queryable; |
| import com.intellij.openapi.ui.ShadowAction; |
| import com.intellij.openapi.util.*; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.openapi.wm.*; |
| import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter; |
| import com.intellij.openapi.wm.ex.ToolWindowManagerEx; |
| import com.intellij.ui.InplaceButton; |
| import com.intellij.ui.SimpleTextAttributes; |
| import com.intellij.ui.docking.DockContainer; |
| import com.intellij.ui.docking.DockManager; |
| import com.intellij.ui.docking.DockableContent; |
| import com.intellij.ui.docking.DragSession; |
| import com.intellij.ui.switcher.SwitchProvider; |
| import com.intellij.ui.switcher.SwitchTarget; |
| import com.intellij.ui.tabs.*; |
| import com.intellij.ui.tabs.impl.JBEditorTabs; |
| import com.intellij.ui.tabs.impl.JBTabsImpl; |
| import com.intellij.util.Consumer; |
| import com.intellij.util.ui.AwtVisitor; |
| import com.intellij.util.ui.TimedDeadzone; |
| import com.intellij.util.ui.UIUtil; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import java.awt.*; |
| import java.awt.event.InputEvent; |
| import java.awt.event.MouseAdapter; |
| import java.awt.event.MouseEvent; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * @author Anton Katilin |
| * @author Vladimir Kondratyev |
| */ |
| public final class EditorTabbedContainer implements Disposable, CloseAction.CloseTarget { |
| private final EditorWindow myWindow; |
| private final Project myProject; |
| private final JBEditorTabs myTabs; |
| |
| @NonNls public static final String HELP_ID = "ideaInterface.editor"; |
| |
| private TabInfo.DragOutDelegate myDragOutDelegate = new MyDragOutDelegate(); |
| |
| EditorTabbedContainer(final EditorWindow window, Project project, final int tabPlacement) { |
| myWindow = window; |
| myProject = project; |
| final ActionManager actionManager = ActionManager.getInstance(); |
| myTabs = new JBEditorTabs(project, actionManager, IdeFocusManager.getInstance(project), this); |
| myTabs.setDataProvider(new MyDataProvider()).setPopupGroup(new Getter<ActionGroup>() { |
| @Override |
| public ActionGroup get() { |
| return (ActionGroup)CustomActionsSchema.getInstance().getCorrectedAction(IdeActions.GROUP_EDITOR_TAB_POPUP); |
| } |
| }, ActionPlaces.EDITOR_TAB_POPUP, false).setNavigationActionsEnabled(false).addTabMouseListener(new TabMouseListener()).getPresentation() |
| .setTabDraggingEnabled(true).setUiDecorator(new UiDecorator() { |
| @Override |
| @NotNull |
| public UiDecoration getDecoration() { |
| return new UiDecoration(null, new Insets(TabsUtil.TAB_VERTICAL_PADDING, 10, TabsUtil.TAB_VERTICAL_PADDING, 10)); |
| } |
| }).setTabLabelActionsMouseDeadzone(TimedDeadzone.NULL).setGhostsAlwaysVisible(true).setTabLabelActionsAutoHide(false) |
| .setActiveTabFillIn(EditorColorsManager.getInstance().getGlobalScheme().getDefaultBackground()).setPaintFocus(false).getJBTabs() |
| .addListener(new TabsListener.Adapter() { |
| @Override |
| public void selectionChanged(final TabInfo oldSelection, final TabInfo newSelection) { |
| final FileEditorManager editorManager = FileEditorManager.getInstance(myProject); |
| final FileEditor oldEditor = oldSelection != null ? editorManager.getSelectedEditor((VirtualFile)oldSelection.getObject()) : null; |
| if (oldEditor != null) { |
| oldEditor.deselectNotify(); |
| } |
| |
| final FileEditor newEditor = editorManager.getSelectedEditor((VirtualFile)newSelection.getObject()); |
| if (newEditor != null) { |
| newEditor.selectNotify(); |
| } |
| } |
| }).setAdditionalSwitchProviderWhenOriginal(new MySwitchProvider()) |
| .setSelectionChangeHandler(new JBTabs.SelectionChangeHandler() { |
| @NotNull |
| @Override |
| public ActionCallback execute(TabInfo info, boolean requestFocus, @NotNull final ActiveRunnable doChangeSelection) { |
| final ActionCallback result = new ActionCallback(); |
| CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { |
| @Override |
| public void run() { |
| ((IdeDocumentHistoryImpl)IdeDocumentHistory.getInstance(myProject)).onSelectionChanged(); |
| result.notify(doChangeSelection.run()); |
| } |
| }, "EditorChange", null); |
| return result; |
| } |
| }).getPresentation().setRequestFocusOnLastFocusedComponent(true); |
| myTabs.addMouseListener(new MouseAdapter() { |
| @Override |
| public void mouseClicked(MouseEvent e) { |
| if (myTabs.findInfo(e) != null || isFloating()) return; |
| if (!e.isPopupTrigger() && SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) { |
| final ActionManager mgr = ActionManager.getInstance(); |
| mgr.tryToExecute(mgr.getAction("HideAllWindows"), e, null, ActionPlaces.UNKNOWN, true); |
| } |
| } |
| }); |
| |
| setTabPlacement(UISettings.getInstance().EDITOR_TAB_PLACEMENT); |
| |
| updateTabBorder(); |
| |
| ((ToolWindowManagerEx)ToolWindowManager.getInstance(myProject)).addToolWindowManagerListener(new ToolWindowManagerAdapter() { |
| @Override |
| public void stateChanged() { |
| updateTabBorder(); |
| } |
| |
| @Override |
| public void toolWindowRegistered(@NotNull final String id) { |
| updateTabBorder(); |
| } |
| }); |
| |
| UISettings.getInstance().addUISettingsListener(new UISettingsListener() { |
| @Override |
| public void uiSettingsChanged(UISettings source) { |
| updateTabBorder(); |
| } |
| }, this); |
| |
| Disposer.register(project, this); |
| } |
| |
| public int getTabCount() { |
| return myTabs.getTabCount(); |
| } |
| |
| public ActionCallback setSelectedIndex(final int indexToSelect) { |
| return setSelectedIndex(indexToSelect, true); |
| } |
| |
| public ActionCallback setSelectedIndex(final int indexToSelect, boolean focusEditor) { |
| if (indexToSelect >= myTabs.getTabCount()) return new ActionCallback.Rejected(); |
| 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.getSize(), window.isFilePinned(file)); |
| } |
| |
| private void updateTabBorder() { |
| if (!myProject.isOpen()) return; |
| |
| ToolWindowManagerEx mgr = (ToolWindowManagerEx)ToolWindowManager.getInstance(myProject); |
| |
| String[] ids = mgr.getToolWindowIds(); |
| |
| Insets border = new Insets(0, 0, 0, 0); |
| |
| UISettings uiSettings = UISettings.getInstance(); |
| |
| List<String> topIds = mgr.getIdsOn(ToolWindowAnchor.TOP); |
| List<String> bottom = mgr.getIdsOn(ToolWindowAnchor.BOTTOM); |
| List<String> rightIds = mgr.getIdsOn(ToolWindowAnchor.RIGHT); |
| List<String> leftIds = mgr.getIdsOn(ToolWindowAnchor.LEFT); |
| |
| if (!uiSettings.HIDE_TOOL_STRIPES && !uiSettings.PRESENTATION_MODE) { |
| border.top = topIds.size() > 0 ? 1 : 0; |
| border.bottom = bottom.size() > 0 ? 1 : 0; |
| border.left = leftIds.size() > 0 ? 1 : 0; |
| border.right = rightIds.size() > 0 ? 1 : 0; |
| } |
| |
| for (String each : ids) { |
| ToolWindow eachWnd = mgr.getToolWindow(each); |
| if (eachWnd == null || !eachWnd.isAvailable()) continue; |
| |
| if (eachWnd.isVisible() && eachWnd.getType() == ToolWindowType.DOCKED) { |
| ToolWindowAnchor eachAnchor = eachWnd.getAnchor(); |
| if (eachAnchor == ToolWindowAnchor.TOP) { |
| border.top = 0; |
| } |
| else if (eachAnchor == ToolWindowAnchor.BOTTOM) { |
| border.bottom = 0; |
| } |
| else if (eachAnchor == ToolWindowAnchor.LEFT) { |
| border.left = 0; |
| } |
| else if (eachAnchor == ToolWindowAnchor.RIGHT) { |
| border.right = 0; |
| } |
| } |
| } |
| |
| myTabs.getPresentation().setPaintBorder(border.top, border.left, border.right, border.bottom).setTabSidePaintBorder(5); |
| } |
| |
| public Component getComponent() { |
| return myTabs.getComponent(); |
| } |
| |
| public ActionCallback removeTabAt(final int componentIndex, int indexToSelect, boolean transferFocus) { |
| TabInfo toSelect = indexToSelect >= 0 && indexToSelect < myTabs.getTabCount() ? myTabs.getTabAt(indexToSelect) : null; |
| final TabInfo info = myTabs.getTabAt(componentIndex); |
| // removing hidden tab happens on end of drag-out, we've already selected the correct tab for this case in dragOutStarted |
| if (info.isHidden()) { |
| toSelect = null; |
| } |
| final ActionCallback callback = myTabs.removeTab(info, toSelect, transferFocus); |
| return myProject.isOpen() ? callback : new ActionCallback.Done(); |
| } |
| |
| public ActionCallback removeTabAt(final int componentIndex, int indexToSelect) { |
| return removeTabAt(componentIndex, indexToSelect, true); |
| } |
| |
| public int getSelectedIndex() { |
| return myTabs.getIndexOf(myTabs.getSelectedInfo()); |
| } |
| |
| public void setForegroundAt(final int index, final Color color) { |
| myTabs.getTabAt(index).setDefaultForeground(color); |
| } |
| |
| public void setWaveColor(final int index, @Nullable final Color color) { |
| final TabInfo tab = myTabs.getTabAt(index); |
| tab.setDefaultStyle(color == null ? SimpleTextAttributes.STYLE_PLAIN : SimpleTextAttributes.STYLE_WAVED); |
| tab.setDefaultWaveColor(color); |
| } |
| |
| public void setIconAt(final int index, final Icon icon) { |
| myTabs.getTabAt(index).setIcon(icon); |
| } |
| |
| public void setTitleAt(final int index, final String text) { |
| myTabs.getTabAt(index).setText(text); |
| } |
| |
| public void setToolTipTextAt(final int index, final String text) { |
| myTabs.getTabAt(index).setTooltipText(text); |
| } |
| |
| public boolean isTitleShortened(int index) { return myTabs.getTabAt(index).isTitleShortened(); } |
| |
| public void setBackgroundColorAt(final int index, final Color color) { |
| myTabs.getTabAt(index).setTabColor(color); |
| } |
| |
| public void setTabLayoutPolicy(final int policy) { |
| switch (policy) { |
| case JTabbedPane.SCROLL_TAB_LAYOUT: |
| myTabs.getPresentation().setSingleRow(true); |
| break; |
| case JTabbedPane.WRAP_TAB_LAYOUT: |
| myTabs.getPresentation().setSingleRow(false); |
| break; |
| default: |
| throw new IllegalArgumentException("Unsupported tab layout policy: " + policy); |
| } |
| } |
| |
| public void setTabPlacement(final int tabPlacement) { |
| switch (tabPlacement) { |
| case SwingConstants.TOP: |
| myTabs.getPresentation().setTabsPosition(JBTabsPosition.top); |
| break; |
| case SwingConstants.BOTTOM: |
| myTabs.getPresentation().setTabsPosition(JBTabsPosition.bottom); |
| break; |
| case SwingConstants.LEFT: |
| myTabs.getPresentation().setTabsPosition(JBTabsPosition.left); |
| break; |
| case SwingConstants.RIGHT: |
| myTabs.getPresentation().setTabsPosition(JBTabsPosition.right); |
| break; |
| default: |
| throw new IllegalArgumentException("Unknown tab placement code=" + tabPlacement); |
| } |
| } |
| |
| @Nullable |
| public Object getSelectedComponent() { |
| final TabInfo info = myTabs.getTargetInfo(); |
| return info != null ? info.getComponent() : null; |
| } |
| |
| public void insertTab(final VirtualFile file, final Icon icon, final JComponent comp, final String tooltip, final int indexToInsert) { |
| |
| TabInfo tab = myTabs.findInfo(file); |
| if (tab != null) return; |
| |
| tab = new TabInfo(comp).setText(calcTabTitle(myProject, file)).setIcon(icon).setTooltipText(tooltip).setObject(file) |
| .setTabColor(calcTabColor(myProject, file)).setDragOutDelegate(myDragOutDelegate); |
| tab.setTestableUi(new MyQueryable(tab)); |
| |
| final DefaultActionGroup tabActions = new DefaultActionGroup(); |
| tabActions.add(new CloseTab(comp, tab)); |
| |
| tab.setTabLabelActions(tabActions, ActionPlaces.EDITOR_TAB); |
| myTabs.addTabSilently(tab, indexToInsert); |
| } |
| |
| public boolean isEmptyVisible() { |
| return myTabs.isEmptyVisible(); |
| } |
| |
| public JBTabs getTabs() { |
| return myTabs; |
| } |
| |
| public void requestFocus(boolean forced) { |
| if (myTabs != null) { |
| IdeFocusManager.getInstance(myProject).requestFocus(myTabs.getComponent(), forced); |
| } |
| } |
| |
| public void setPaintBlocked(boolean blocked) { |
| ((JBTabsImpl)myTabs).setPaintBlocked(blocked, true); |
| } |
| |
| private static class MyQueryable implements Queryable { |
| |
| private final TabInfo myTab; |
| |
| public MyQueryable(TabInfo tab) { |
| myTab = tab; |
| } |
| |
| @Override |
| public void putInfo(@NotNull Map<String, String> info) { |
| info.put("editorTab", myTab.getText()); |
| } |
| } |
| |
| public static String calcTabTitle(final Project project, final VirtualFile file) { |
| for (EditorTabTitleProvider provider : Extensions.getExtensions(EditorTabTitleProvider.EP_NAME)) { |
| final String result = provider.getEditorTabTitle(project, file); |
| if (result != null) { |
| return result; |
| } |
| } |
| |
| return file.getPresentableName(); |
| } |
| |
| @Nullable |
| public static Color calcTabColor(@NotNull Project project, @NotNull VirtualFile file) { |
| for (EditorTabColorProvider provider : Extensions.getExtensions(EditorTabColorProvider.EP_NAME)) { |
| final Color result = provider.getEditorTabColor(project, file); |
| if (result != null) { |
| return result; |
| } |
| } |
| |
| return null; |
| } |
| |
| public Component getComponentAt(final int i) { |
| final TabInfo tab = myTabs.getTabAt(i); |
| return tab.getComponent(); |
| } |
| |
| @Override |
| public void dispose() { |
| |
| } |
| |
| private class CloseTab extends AnAction implements DumbAware { |
| |
| ShadowAction myShadow; |
| private final TabInfo myTabInfo; |
| |
| public CloseTab(JComponent c, TabInfo info) { |
| myTabInfo = info; |
| myShadow = new ShadowAction(this, ActionManager.getInstance().getAction(IdeActions.ACTION_CLOSE), c); |
| } |
| |
| @Override |
| public void update(final AnActionEvent e) { |
| e.getPresentation().setIcon(myTabs.isEditorTabs() ? AllIcons.Actions.CloseNew : AllIcons.Actions.Close); |
| e.getPresentation().setHoveredIcon(myTabs.isEditorTabs()? AllIcons.Actions.CloseNewHovered : AllIcons.Actions.CloseHovered); |
| e.getPresentation().setVisible(UISettings.getInstance().SHOW_CLOSE_BUTTON); |
| e.getPresentation().setText("Close. Alt-click to close others."); |
| } |
| |
| @Override |
| public void actionPerformed(final AnActionEvent e) { |
| final FileEditorManagerEx mgr = FileEditorManagerEx.getInstanceEx(myProject); |
| EditorWindow window; |
| final VirtualFile file = (VirtualFile)myTabInfo.getObject(); |
| if (ActionPlaces.EDITOR_TAB.equals(e.getPlace())) { |
| window = myWindow; |
| } |
| else { |
| window = mgr.getCurrentWindow(); |
| } |
| |
| if (window != null) { |
| if ((e.getModifiers() & InputEvent.ALT_MASK) != 0) { |
| window.closeAllExcept(file); |
| } |
| else { |
| if (window.findFileComposite(file) != null) { |
| mgr.closeFile(file, window); |
| } |
| } |
| } |
| } |
| } |
| |
| private class MyDataProvider implements DataProvider { |
| @Override |
| public Object getData(@NonNls final String dataId) { |
| if (CommonDataKeys.PROJECT.is(dataId)) { |
| return myProject; |
| } |
| if (CommonDataKeys.VIRTUAL_FILE.is(dataId)) { |
| final VirtualFile selectedFile = myWindow.getSelectedFile(); |
| return selectedFile != null && selectedFile.isValid() ? selectedFile : null; |
| } |
| if (EditorWindow.DATA_KEY.is(dataId)) { |
| return myWindow; |
| } |
| if (PlatformDataKeys.HELP_ID.is(dataId)) { |
| return HELP_ID; |
| } |
| |
| if (CloseAction.CloseTarget.KEY.is(dataId)) { |
| TabInfo selected = myTabs.getSelectedInfo(); |
| if (selected != null) { |
| return EditorTabbedContainer.this; |
| } |
| } |
| |
| if (EditorWindow.DATA_KEY.is(dataId)) { |
| return myWindow; |
| } |
| |
| return null; |
| } |
| } |
| |
| @Override |
| public void close() { |
| TabInfo selected = myTabs.getTargetInfo(); |
| if (selected == null) return; |
| |
| final VirtualFile file = (VirtualFile)selected.getObject(); |
| final FileEditorManagerEx mgr = FileEditorManagerEx.getInstanceEx(myProject); |
| |
| AsyncResult<EditorWindow> window = mgr.getActiveWindow(); |
| window.doWhenDone(new Consumer<EditorWindow>() { |
| @Override |
| public void consume(EditorWindow wnd) { |
| if (wnd != null) { |
| if (wnd.findFileComposite(file) != null) { |
| mgr.closeFile(file, wnd); |
| } |
| } |
| } |
| }); |
| } |
| |
| private boolean isFloating() { |
| return myWindow.getOwner().isFloating(); |
| } |
| |
| private class TabMouseListener extends MouseAdapter { |
| private int myActionClickCount; |
| |
| @Override |
| public void mouseReleased(MouseEvent e) { |
| if (UIUtil.isCloseClick(e, MouseEvent.MOUSE_RELEASED)) { |
| final TabInfo info = myTabs.findInfo(e); |
| if (info != null) { |
| IdeEventQueue.getInstance().blockNextEvents(e); |
| FileEditorManagerEx.getInstanceEx(myProject).closeFile((VirtualFile)info.getObject(), myWindow); |
| } |
| } |
| } |
| |
| @Override |
| public void mousePressed(final MouseEvent e) { |
| if (UIUtil.isActionClick(e)) { |
| if (e.getClickCount() == 1) { |
| myActionClickCount = 0; |
| } |
| // clicks on the close window button don't count in determining whether we have a double-click on tab (IDEA-70403) |
| final Component deepestComponent = SwingUtilities.getDeepestComponentAt(e.getComponent(), e.getX(), e.getY()); |
| if (!(deepestComponent instanceof InplaceButton)) { |
| myActionClickCount++; |
| } |
| if (myActionClickCount > 1 && !isFloating()) { |
| final ActionManager mgr = ActionManager.getInstance(); |
| mgr.tryToExecute(mgr.getAction("HideAllWindows"), e, null, ActionPlaces.UNKNOWN, true); |
| } |
| } |
| } |
| |
| @Override |
| public void mouseClicked(MouseEvent e) { |
| if (UIUtil.isActionClick(e, MouseEvent.MOUSE_CLICKED) && (e.isMetaDown() || (!SystemInfo.isMac && e.isControlDown()))) { |
| final TabInfo info = myTabs.findInfo(e); |
| if (info != null && info.getObject() != null) { |
| final VirtualFile vFile = (VirtualFile)info.getObject(); |
| ShowFilePathAction.show(vFile, e); |
| } |
| } |
| } |
| } |
| |
| private class MySwitchProvider implements SwitchProvider { |
| @Override |
| public List<SwitchTarget> getTargets(final boolean onlyVisible, boolean originalProvider) { |
| final ArrayList<SwitchTarget> result = new ArrayList<SwitchTarget>(); |
| TabInfo selected = myTabs.getSelectedInfo(); |
| new AwtVisitor(selected.getComponent()) { |
| @Override |
| public boolean visit(Component component) { |
| if (component instanceof JBTabs) { |
| JBTabs tabs = (JBTabs)component; |
| if (tabs != myTabs) { |
| result.addAll(tabs.getTargets(onlyVisible, false)); |
| return true; |
| } |
| } |
| return false; |
| } |
| }; |
| return result; |
| } |
| |
| @Override |
| public SwitchTarget getCurrentTarget() { |
| TabInfo selected = myTabs.getSelectedInfo(); |
| final Ref<SwitchTarget> targetRef = new Ref<SwitchTarget>(); |
| new AwtVisitor(selected.getComponent()) { |
| @Override |
| public boolean visit(Component component) { |
| if (component instanceof JBTabs) { |
| JBTabs tabs = (JBTabs)component; |
| if (tabs != myTabs) { |
| targetRef.set(tabs.getCurrentTarget()); |
| return true; |
| } |
| } |
| return false; |
| } |
| }; |
| |
| return targetRef.get(); |
| } |
| |
| @Override |
| public JComponent getComponent() { |
| return null; |
| } |
| |
| @Override |
| public boolean isCycleRoot() { |
| return false; |
| } |
| } |
| |
| class MyDragOutDelegate implements TabInfo.DragOutDelegate { |
| |
| private VirtualFile 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 = (VirtualFile)info.getObject(); |
| Presentation presentation = new Presentation(info.getText()); |
| presentation.setIcon(info.getIcon()); |
| mySession = getDockManager().createDragSession(mouseEvent, createDockableEditor(myProject, img, myFile, presentation, myWindow)); |
| } |
| |
| 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 = 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); |
| } |
| 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; |
| } |
| |
| } |
| |
| public static class DockableEditor implements DockableContent<VirtualFile> { |
| final Image myImg; |
| private DockableEditorTabbedContainer myContainer; |
| private Presentation myPresentation; |
| private Dimension myPreferredSize; |
| private boolean myPinned; |
| private VirtualFile myFile; |
| |
| public DockableEditor(Project project, Image img, VirtualFile file, Presentation presentation, Dimension preferredSize, boolean isFilePinned) { |
| myImg = img; |
| myFile = file; |
| myPresentation = presentation; |
| myContainer = new DockableEditorTabbedContainer(project); |
| myPreferredSize = preferredSize; |
| myPinned = isFilePinned; |
| } |
| |
| @NotNull |
| @Override |
| public VirtualFile getKey() { |
| return myFile; |
| } |
| |
| @Override |
| public Image getPreviewImage() { |
| return myImg; |
| } |
| |
| @Override |
| public Dimension getPreferredSize() { |
| return myPreferredSize; |
| } |
| |
| @Override |
| public String getDockContainerType() { |
| return DockableEditorContainerFactory.TYPE; |
| } |
| |
| @Override |
| public Presentation getPresentation() { |
| return myPresentation; |
| } |
| |
| @Override |
| public void close() { |
| myContainer.close(myFile); |
| } |
| |
| public VirtualFile getFile() { |
| return myFile; |
| } |
| |
| public boolean isPinned() { |
| return myPinned; |
| } |
| } |
| |
| } |