Thursday, September 25, 2008

Drag and Drop Improvements in Eclipse

One feature that IDE users are accustomed to is dragging files from Windows Explorer and dropping them on the application window to have them handled by that app.

With the 3.3 Platform, Eclipse added the "Editor area drag and drop" functionality, which aims at implementing this feature.

Unfortunately, there is still some limitations that need to be overcome to handle how users expect a native application to behave.

Handling files that open with external editors

The first thing that the user can notice about Eclipe's handling of dropped files is that for some file types dropped onto the workbench, external editors are launched to open the file type instead of Eclipse itself.


The most obvious example is when the user drags and drops a .bat file in the Eclipse workbench.

Instead of editing the content of the file in a text editor, as the user would expect, Eclipse actually launches the .bat file in a Windows command prompt, mimicking the same behavior as if the user double-clicked it in the navigator pane.

This is very inconsistent, since if the same file is dragged not from Windows Explorer but from an Eclipse project and dropped on the same editor, the .bat file is now properly open in an editor window instead of being launched in a command prompt.

This issue doesn't only affect .bat files, but all files that map to a system editor in Eclipse.

If the user wanted to simply have Windows to handle the .bat file and not Eclipse, he would have simply double-clicked it, and not took the effort to drop it on top of the Eclipse workbench.

Obviously, Eclipse doesn't do what user expect with those kind of files.

Lack of extensibility

Drag and dropping files in an Eclipse workbench demonstrate the general intent of the user to have Eclipse handle that file.

For some files, that may coincide with opening them in the editor, but with other files, Eclipse handling of the file may mean something very different.

For example, dropping an Eclipse project directory on the Eclipse workbench demonstrate that the user doesn't want to edit the folder, but import the project in the current workspace. The same is most likely with .project files as well.

Note that since the user can't currently double-click the .project file in Windows explorer and have Eclipse be open and handle the project, this is the only way he can have to conveniently import projects without having to go through the import wizard.

By dropping a .mcp or .vcproj file on the Eclipse workbench, the user demonstrate his intent of having those CodeWarrior and Visual Studio projects be imported in Eclipse, preferably by having a wizard come up.

Another thing that is typical for C/C++ IDE is dropping an executable on the IDE in order to start a debugging session for that executable.

In all those case, the expected Eclipse behavior by the user is different from what he would expect if he double-clicked the same files in the Eclipse navigator (in which case, he would expect to expand the project directory, to launch CodeWarrior or Visual Studio, and to run the executable respectively).

All those features are impossible to implement with the current Drag and Drop feature which is not extensible.

Our improvements to the Editor area Drag and Drop feature.

In order to overcome the limitations mentioned above, we made the following improvements in the Editor area drag and drop feature:

  1. We extended the drop target for the general drag and drop workbench mechanism. Since the Eclipse workbench in general should handle file and folders dropped from Windows Explorer, the user can now use the top part of the Eclipse Workbench window to drop files.

    Note that we wanted to include the top most section of the workbench window, but we couldn't find a way to include it without including the whole shell at the same time.
  2. We added the org.eclipse.ui.ide.dropHandler extension point to allow a flexible implementation and resolution of the handling of files and folders dropped on the Eclipse workbench (see more details below).
  3. We provided default dropHandlers to handle files in a proper way (without resorting to external editors) and to handle project directories and .project files by importing the project in the current workspace.
  4. We provided a conflict resolution mechanism that detects when two or more handlers declare supporting the same file and let the user choose between them in a convenient dialog.

Algorithm and Extensibility API

The general workbench Drop Handler algorithm relies solely on the dropHandler extensions to be able to handle dropped files and folders on the Eclipse workbench.

Each handler must have the following attributes:
  • A user visible name
  • An icon
  • A handler class, implementing the IDropHandler interface (as described below)
  • A unique string ID.
  • A set of rules determining if a given file or folder is supported by the DropHandler.
The rules can be any combination of the following:
  1. An inspector class, implementing the IDropHandlerInspector
  2. Any number of typenames, which consist of the type of the object (file or directory) along with a regex pattern for the file name (such as "\.project").
  3. Any number of file extensions, which consist of a pattern matching a file extension, such as "txt".
  4. Any number of content types, which consist of the Eclipse content type IDs used in the Platform ContentTypeManager.
  5. A lastInspector class implementing the IDropHandlerInspector as well.
When a file or folder is dropped on the Eclipse workbench, the workbench drop feature will iterate through all inspectors for all existing dropHandlers. If one inspector matches the file or folder, its handler class will be used to handle the file or folder and the matching process will end.

If no matching inspectors are found, all typenames will be tested, then all extensions, followed by all content types and finally all lastInspectors.

If two or more dropHandlers are found matching for the same rule level, the Conflict Resolution dialog will be displayed to the user to know which dropHandler to choose, unless a precedence already has been recorded by the user.

The following is an example of a Project Handler extension point:

<extension point="org.eclipse.ui.ide.dropHandler">
<handler class="org.eclipse.ui.internal.ide.dnd.ProjectDropHandler"
icon="icons/full/obj16/prj_obj.gif"
id="org.eclipse.ui.ide.dnd.ProjectDropHandler"
name="%DropHandlers.ProjectDropHandler">
<inspector class="org.eclipse.ui.internal.ide.dnd.ProjectDropHandler">
</inspector>
<typeName name="\.project"
type="file">
</typeName>
</handler>
</extension>
The IDropHandler interface is defined as follows:
package org.eclipse.ui.ide.dnd;

import org.eclipse.core.runtime.IPath;

/**
* Interface implemented by a dropSupport extension point to
* handle a file or folder dropped on the workbench.
*
*/

public interface IDropHandler {

/** Handles a dropped file or folder on top of the workbench.
* @param path The full absolute path of the file or folder dropped.
*/

public void handle(IPath path);
}

And the IDropHandlerInspector as follows:
package org.eclipse.ui.ide.dnd;

import org.eclipse.core.runtime.IPath;

/**
* Interface implemented by a dropSupport extension point to
* handle a file or folder dropped on the workbench.
*
*/

public interface IDropHandlerInspector {

/**Returns true or false whether a handler support the type
* of file or folder that was dropped on the workbench.
* @param path The full absolute path of the file or folder dropped.
* @return true if the handler support handling the file or folder pointer by path, false otherwise.
*/

public boolean handles(IPath path);
}

Conclusion


We hope that our improvements can be useful to other Eclipse users, and welcome your comments, questions and criticisms!

Our changes are freely available in the following Eclipse bug report, and we hope to be able to contribute the changes back to the Eclipse standard distribution:


That contains a patch with the implementation of our drag and drop feature improvement.

No comments: