Changes required when adopting 3.1 mechanisms and APIs

This section describes changes that are required if you are trying to change your 3.0 plug-in to adopt the 3.1 mechanisms and APIs.

Platform undo/redo support

Eclipse 3.1 provides a new infrastructure for defining undoable operations and a shared operation history that keeps track of operations that have been executed, undone, and redone. The various undo frameworks provided by add-on plug-ins should migrated over time to the platform operation support, so that clients of these frameworks can integrate more deeply with the platform and make their undoable operations available for undo in other plug-in views and editors. See the Undoable operations documentation for basic information about adding undo support to a plug-in. Plug-ins that already define undo support or use another framework can be migrated to the new undo support in a staged fashion, as described below.

Migrating plug-in specific operation (command) classes to IUndoableOperation

Plug-ins that already define classes describing their undoable operations should add an implementation for the interface IUndoableOperation to their operation/command classes. Plug-ins may still use older frameworks for managing the history (command stack) if necessary, but providing an interface for IUndoableOperation allows a plug-in's clients to use the same operations in the platform operations history, and to mix and match undoable operations from different plug-ins. This strategy is similar to that used by the SDK text editors to migrate to the new operations framework. If a direct mapping of the interface is not possible, wrappers can be used to map IUndoableOperation protocol to legacy undo objects. This strategy is used by the Platform/JDT refactoring support. Migration of the operation/command classes to IUndoableOperation is an important step because it allows the undoable operations from different frameworks to be utilized by other plug-ins without either plug-in having to migrate completely.

Migrating command stacks with IOperationHistory

Once undoable operations or commands are expressed in terms of IUndoableOperation, plug-ins that define an undo history (command stack) for keeping track of the undoable and redoable operations can migrate to the platform operations history by defining an IUndoContext that represents their undo history. Undo histories that were previously managed locally can be merged into the common operation history by defining a unique undo context either for each part or for each model object, adding the appropriate undo context to each operation, and then adding the operation to the platform operation history. Undo histories with more global scope can be implemented by defining a unique undo context representing that undo scope, assigning that context to each operation, and then adding the operation to the platform operation history. See the Undoable operations documentation for examples of creating undo contexts, assigning them, and adding operations to the platform operation history.

Defining undoable operations global to the workbench

Plug-ins that wish their operations to be undoable from workbench views such as the Navigator or Package Explorer should assign the workbench undo context to their operations. See the Undoable operations documentation for more information about this undo context and how it can be retrieved by both workbench and headless plug-ins.

Platform undo/redo action handlers

Plug-ins that do not define an undo infrastructure or undoable operations, but wish to provide access to the platform's undo history, should consider retargeting the global undo and redo action handlers with the new common undo and redo action handlers. The action handlers should be assigned an undo context specifying which undo and redo history is to be shown. Plug-ins can use their locally defined undo contexts for showing "part-local" undo and redo history. The workbench undo context can be used for showing workbench-wide undo and redo history. Again, the Undoable operations documentation has a complete example.

Migrating text operation actions to the common action handlers

Migrating text editor undo and redo actions is a bit different than simple retargeting of the global undo/redo action handlers. The AbstractTextEditor framework defines common text actions using a parameterized TextOperationAction. These actions are stored locally in the framework and used to dispatch various commands to an editor's text operation target. For text undo to work properly, the text editor framework relies on the presence of text operation actions with the proper id's (ITextEditorActionConstants.REDO and ITextEditorActionConstants.UNDO).

AbstractTextEditor has been migrated so that it creates the common action handlers, while still assigning them to the TextOperationAction table with their legacy id's. In this way, the new undo and redo action handlers can be retrieved using the legacy techniques for retrieving the action and performing an operation. Text editors in the AbstractTextEditor hierarchy will inherit this behavior.

Editors that do not inherit this behavior from AbstractTextEditor should consider migrating any existing undo and redo actions to use the new handlers. Editors with legacy undo and redo TextOperationActions will still have working local undo support, since the JFace Text undo manager API used by these actions is still supported. However, the undo and redo action labels will not be consistent with the new Eclipse SDK undo/redo actions, which show the name of the available undo or redo operation. To create the common undo and redo action handlers, the undo context used by the text viewer's undo manager should be used when creating the action handlers, and those handlers should be set into the editor using the appropriate ITextEditorActionConstants id. See AbstractTextEditor.createUndoRedoActions() and AbstractTextEditor.getUndoContext() for a detailed example. Editors that rely on an EditorActionBarContributor subclass to add to the action bars of their editors can use a similar technique by creating undo and redo action handlers and setting them when the active editor is set.

Help Enhancements

Information Search

Plug-ins that contribute search pages into the Search dialog should consider porting all their information-style searches into federated search engines. Since 3.1, all information-style search is separated from the workbench-artifact search. Information search engines are run in parallel as background jobs and their results collated in the new Help view. See Help Search for more details.

Dynamic help

The new dynamic help view will work with existing context IDs that are statically associated with widgets in workbench parts and dialogs. However, if you catch help event yourself and show help, dynamic help view will not be able to show anything useful. To fix the problem, you should adapt to the new IContextProvider interface as described in Dynamic Context Help document.

JFace Preference Stores

As of release 3.1 the org.eclipse.jface.preference.IPreferenceStore that is returned from AbstractUIPlugin.getPreferenceStore() will be an instance of org.eclipse.ui.preferences.ScopedPreferenceStore. The ScopedPreferenceStore uses the org.eclipse.core.runtime.preferences API to manage preferences. In 3.0 it used the compatibility layer to interface with an instance of org.eclipse.core.runtime.Preferences.

In 3.1 we have disambiguated IPreferenceStore to be more specific about the types of the values sent in preference changed events. The IPreferenceStore from AbstractUIPlugin#getPreferenceStore has the same behavior as before, but it is now specified more clearly.

Typing: org.eclipse.jface.util.IPropertyChangeListener added to an IPreferenceStore can potentially get two types of old and new values - typed or String representations. Any event generated by a call to a typed IPreferenceStore API (such as setValue(String key, boolean value) will generate a typed event. However it is also possible that events will be propagated from the core runtime preferences which generate an untyped event (for instance on a preference import). Property listeners need to be prepared for both. Note also that typed events will not be propagating primitive types so a call to setValue(String key, boolean value) will result in an event where the oldValue and newValue are Booleans.

putValue: IPreferenceStore.putValue(String key, String value) will not generate a change event. This API is meant to be used for private preferences that no listener would want to react to.

initializeDefaultPreferences. This API was deprecated in Eclipse 3.0 as it is only fired if the compatibility layer is used. As most plug-ins rely on AbstractUIPlugin#getPreferenceStore to get their preference store this was being fired on plug-in start-up previously. If your plug-in does not access the compatibility layer itself then this method may not be fired. It is recommended that you create a org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer to handle your preference initialization.