/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.internal.ide; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Path; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DropTargetAdapter; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.FileTransfer; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorDescriptor; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorRegistry; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.part.EditorInputTransfer; import org.eclipse.ui.part.EditorInputTransfer.EditorInputData; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.part.MarkerTransfer; import org.eclipse.ui.part.ResourceTransfer; /** * An editor area drop adapter to handle transfer types * <code>EditorInputTransfer</code>, <code>MarkerTransfer</code>, * and <code>ResourceTransfer</code>. */ public class EditorAreaDropAdapter extends DropTargetAdapter { private IWorkbenchWindow window; /** * Constructs a new EditorAreaDropAdapter. * @param window the workbench window */ public EditorAreaDropAdapter(IWorkbenchWindow window) { this.window = window; } @Override public void dragEnter(DropTargetEvent event) { // always indicate a copy event.detail = DND.DROP_COPY; event.feedback = DND.FEEDBACK_NONE; } @Override public void dragOver(DropTargetEvent event) { // always indicate a copy event.detail = DND.DROP_COPY; event.feedback = DND.FEEDBACK_NONE; } @Override public void dragOperationChanged(DropTargetEvent event) { // always indicate a copy event.detail = DND.DROP_COPY; event.feedback = DND.FEEDBACK_NONE; } @Override public void drop(final DropTargetEvent event) { Display d = window.getShell().getDisplay(); final IWorkbenchPage page = window.getActivePage(); if (page != null) { d.asyncExec(() -> asyncDrop(event, page)); } } private void asyncDrop(DropTargetEvent event, IWorkbenchPage page) { /* Open Editor for generic IEditorInput */ if (EditorInputTransfer.getInstance().isSupportedType( event.currentDataType)) { /* event.data is an array of EditorInputData, which contains an IEditorInput and * the corresponding editorId */ Assert.isTrue(event.data instanceof EditorInputTransfer.EditorInputData[]); for (EditorInputData editorInputData : (EditorInputTransfer.EditorInputData[]) event.data) { IEditorInput editorInput = editorInputData.input; String editorId = editorInputData.editorId; openNonExternalEditor(page, editorInput, editorId); } } /* Open Editor for Marker (e.g. Tasks, Bookmarks, etc) */ else if (MarkerTransfer.getInstance().isSupportedType(event.currentDataType)) { Assert.isTrue(event.data instanceof IMarker[]); for (IMarker marker : (IMarker[]) event.data) { openNonExternalEditor(page, marker); } } /* Open Editor for resource */ else if (ResourceTransfer.getInstance().isSupportedType(event.currentDataType)) { Assert.isTrue(event.data instanceof IResource[]); for (IResource resource : (IResource[]) event.data) { if (resource instanceof IFile) { IFile file = (IFile) resource; if (!file.isPhantom()) openNonExternalEditor(page, file); } } } /* Open Editor for file from local file system */ else if (FileTransfer.getInstance().isSupportedType( event.currentDataType)) { Assert.isTrue(event.data instanceof String[]); for (String path : (String[]) event.data) { IFileStore fileStore = EFS.getLocalFileSystem().getStore(new Path(path)); try { IDE.openEditorOnFileStore(page, fileStore); } catch (PartInitException e) { // silently ignore problems opening the editor } } } } /** * Opens an editor for the given file on the given workbench page in response * to a drop on the workbench editor area. In contrast to other ways of opening * an editor, we never open an external editor in this case (since external * editors appear in their own window and not in the editor area). * The operation fails silently if there is no suitable editor to open. * * @param page the workbench page * @param file the file to open * @return the editor part that was opened, or <code>null</code> if no editor * was opened */ private IEditorPart openNonExternalEditor(IWorkbenchPage page, IFile file) { IEditorPart result; try { // find out which editor we would normal open IEditorDescriptor defaultEditorDesc = IDE.getDefaultEditor(file); if (defaultEditorDesc != null && !defaultEditorDesc.isOpenExternal()) { // open an internal or in-place editor result = IDE.openEditor(page, file, true); } else { // never open an external editor in response to a drop // check the OS for in-place editor (OLE on Win32) IEditorRegistry editorReg = PlatformUI.getWorkbench() .getEditorRegistry(); IEditorDescriptor editorDesc = null; if (editorReg.isSystemInPlaceEditorAvailable(file.getName())) { editorDesc = editorReg .findEditor(IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID); } // next lookup the default text editor if (editorDesc == null) { editorDesc = editorReg .findEditor(IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID); } // if no valid editor found, bail out if (editorDesc == null) { throw new PartInitException(IDEWorkbenchMessages.IDE_noFileEditorFound); } // open the editor on the file result = page.openEditor(new FileEditorInput(file), editorDesc .getId(), true); } } catch (PartInitException e) { // silently ignore problems opening the editor result = null; } return result; } /** * Opens an editor for the given marker on the given workbench page in response * to a drop on the workbench editor area. In contrast to other ways of opening * an editor, we never open an external editor in this case (since external * editors appear in their own window and not in the editor area). * The operation fails silently if there is no suitable editor to open. * * @param page the workbench page * @param marker the marker to open * @return the editor part that was opened, or <code>null</code> if no editor * was opened */ private IEditorPart openNonExternalEditor(IWorkbenchPage page, IMarker marker) { IEditorPart result; try { // get the marker resource file if (!(marker.getResource() instanceof IFile)) { return null; } IFile file = (IFile) marker.getResource(); // get the preferred editor id from the marker IEditorDescriptor editorDesc = null; try { String editorID = (String) marker .getAttribute(IDE.EDITOR_ID_ATTR); if (editorID != null) { IEditorRegistry editorReg = PlatformUI.getWorkbench() .getEditorRegistry(); editorDesc = editorReg.findEditor(editorID); } } catch (CoreException e) { // ignore problems with getting the marker } // open the editor on the marker resource file if (editorDesc != null && !editorDesc.isOpenExternal()) { result = page.openEditor(new FileEditorInput(file), editorDesc .getId(), true); } else { result = openNonExternalEditor(page, file); } // get the editor to update its position based on the marker if (result != null) { IDE.gotoMarker(result, marker); } } catch (PartInitException e) { // silently ignore problems opening the editor result = null; } return result; } /** * Opens an editor for the given editor input and editor id combination on the * given workbench page in response to a drop on the workbench editor area. * In contrast to other ways of opening an editor, we never open an external * editor in this case (since external editors appear in their own window and * not in the editor area). The operation fails silently if the editor * cannot be opened. * * @param page the workbench page * @param editorInput the editor input * @param editorId the editor id * @return the editor part that was opened, or <code>null</code> if no editor * was opened */ private IEditorPart openNonExternalEditor(IWorkbenchPage page, IEditorInput editorInput, String editorId) { IEditorPart result; try { IEditorRegistry editorReg = PlatformUI.getWorkbench() .getEditorRegistry(); IEditorDescriptor editorDesc = editorReg.findEditor(editorId); if (editorDesc != null && !editorDesc.isOpenExternal()) { result = page.openEditor(editorInput, editorId); } else { result = null; } } catch (PartInitException e) { // silently ignore problems opening the editor result = null; } return result; } }