de.tu_berlin.cs.tfs.muvitorkit.ui
Class MuvitorTreeEditor

java.lang.Object
  extended by org.eclipse.core.commands.common.EventManager
      extended by org.eclipse.ui.part.WorkbenchPart
          extended by org.eclipse.ui.part.EditorPart
              extended by de.tu_berlin.cs.tfs.muvitorkit.ui.MuvitorTreeEditor
All Implemented Interfaces:
EventListener, IAdaptable, IExecutableExtension, CommandStackListener, IGotoMarker, IEditorPart, IPersistable, IPersistableEditor, ISaveablePart, ISelectionListener, IWorkbenchPart, IWorkbenchPart2, IWorkbenchPart3, IWorkbenchPartOrientation

public abstract class MuvitorTreeEditor
extends EditorPart
implements CommandStackListener, ISelectionListener, IPersistableEditor, IGotoMarker

This is a rich-featured abstract implementation of an EditorPart with a GEF MuvitorTreeEditor.EditorTreeViewer. Its purpose is to provide many generic features available to GEF editors, or at least to make them easy to use by editor programmers. Programmers only need to configure the editor by passing some information by implementing the abstract methods.

Prerequisites:

When instantiated (and in createPartControl(Composite)) this class does the following:

  1. It creates a DefaultEditDomain and sets itself as the EditorPart.
  2. Looks up the perspective defined for the plugin and opens it.
  3. A MuvitorTreeEditor.EditorTreeViewer is created.
  4. The MuvitorTreeEditor.EditorTreeViewer's control is registered as resource user in SWTResourceManager so that we can use this to manage color, fonts, and images. These will then be automatically disposed when the editor gets closed.
  5. Sets the TreeViewer in the EditDomain and listens to selection changes on the workbench page. The TreeViewer is set as selection provider for this editor.
  6. Installs a SelectionSynchronizer on the MuvitorTreeEditor.EditorTreeViewer.
  7. MuvitorTreeEditor.EditorTreeViewer is set as ISelectionProvider for this IEditorSite.
  8. Sets the edit part factory, contents, and context menu for the TreeViewer determined by abstract methods.
  9. Sets a standard KeyHandler for the MuvitorTreeEditor.EditorTreeViewer.

Additionally it provides the following features:

  • The editor will hide a MuvitorPageBookView automatically when its model has been deleted (i.e. model.eResource() == null).
  • When being disposed the editor stores information (IDs) about the opened views to the plugin's preferences to reopen them when the editor is started again.

    This class offers several static methods to open and close MuvitorPageBookViews: showView(EObject) and #closeViewsShowing(EObject) for closing views showing a specific model and closeViews(MuvitorTreeEditor) for closing all views showing a model whose root container is this editor's model root.

    The following methods have to be implemented by subclasses. See their documentation for useful hints.

    Rating red

    Nested Class Summary
     class MuvitorTreeEditor.EditorTreeViewer
              This special TreeViewer is needed to allow the EditParts to access the editor.
     
    Field Summary
    static String fileExtension
              The file extension this editor reacts on as specified in plugin.xml
     
    Fields inherited from interface org.eclipse.ui.IEditorPart
    PROP_DIRTY, PROP_INPUT
     
    Fields inherited from interface org.eclipse.ui.IWorkbenchPart
    PROP_TITLE
     
    Constructor Summary
    protected MuvitorTreeEditor()
              The standard constructor creates a DefaultEditDomain and registers itself as a CommandStackListener on the domains CommandStack.
     
    Method Summary
    static ArrayList<EObject> closeViews(MuvitorTreeEditor editor)
              Similar to closeViewShowing(EObject) this method closes all views showing an EObject that belongs to the specified editor, according to IDUtil.getHostEditor(EObject).
    static void closeViewShowing(EObject model)
              This is Muvitor's main method for closing a view in the workbench showing a specific EObject.
     void commandStackChanged(EventObject event)
              When the command stack changes, the actions are updated.
    protected abstract  ContextMenuProviderWithActionRegistry createContextMenuProvider(TreeViewer viewer)
              Subclasses must implement to specify the ContextMenuProviderWithActionRegistry that should be used by this editor's MuvitorTreeEditor.EditorTreeViewer and is responsible to show the created actions in the context menu.
    protected abstract  void createCustomActions()
              To be implemented by subclasses.
    protected abstract  EObject createDefaultModel()
              Subclasses have to generate a default model in this method.
    protected  List<EObject> createDefaultModels()
              By default, MuvitorTreeEditor uses a single model root, which will be created in createDefaultModel().
     IMarker createErrorMarker(EObject model, String location, String message)
              Create an eclipse error marker for the currently edited file on given location with specified message.
     void createPartControl(Composite parent)
              Realizes the editor by creating its Control.
    protected abstract  EditPartFactory createTreeEditPartFactory()
              Subclasses must implement this to specify the EditPartFactory that should be used by this editor's MuvitorTreeEditor.EditorTreeViewer.
     void dispose()
              Tries to close views for all models of the resource that have possibly been opened.
     void doSave(IProgressMonitor monitor)
               
     void doSaveAs()
               
     ArrayList<IMarker> findProblemMarkers(String attrName)
              Convenience method that collects all problem markers like findProblemMarkers(String, Object) for which the attribute has been set with any value.
     ArrayList<IMarker> findProblemMarkers(String attrName, Object attrValue)
              Helper method to find problem markers with specific attribute values.
    protected  void firePropertyChange(int property)
               
    protected  ActionRegistry getActionRegistry()
              Lazily creates, initializes and returns the action registry.
     Object getAdapter(Class type)
              IMPORTANT certain requests, such as the property sheet, may be made before or after createPartControl(Composite) is called.
    protected  CommandStack getCommandStack()
               
    protected  DefaultEditDomain getEditDomain()
               
    protected  KeyHandler getKeyHandler()
              Need to create key handler lazily because accessing the action registry creates the actions which needs the editor site etc.
     List<EObject> getModelRoots()
              Returns the list of EObject models that have been loaded by the EMFModelManager.
     EObject getPrimaryModelRoot()
              Returns by default the first model in the list of EObject models that have been loaded by the EMFModelManager.
     IStatusLineManager getStatusLineManager()
              This can be used to display messages in this page's status line.
     TreeViewer getTreeViewer()
               
     void gotoMarker(IMarker marker)
              This default implementation of IGotoMarker tries to resolve the marker's IMarker.SOURCE_ID attribute to an EObject model.
     void init(IEditorSite site, IEditorInput input)
              Sets the site and input for this editor and opens the unique perspective defined in plugin.xml.
     boolean isDirty()
              Returns true if the command stack is dirty
     boolean isSaveAsAllowed()
               
    protected  IAction registerAction(IAction action)
              Registers the action with the editor's action registry.
    protected  IAction registerActionOnToolBar(IAction action)
              Registers the action with the editor's action registry and puts it on this editor's tool bar.
    static void registerViewID(EClass eClass, String viewID)
              Associate a class of models with the ID of a MuvitorPageBookView that has been registered in plugin.xml.
     void restoreState(IMemento memento)
              Restores the views that were opened when Eclipse was closed during an editor session if the editor is still able to work on the same file.
     void revertToLastSaved()
              This method implements support for the Muvitor's RevertAction.
    protected  void save(IFile file, IProgressMonitor monitor)
              This method saves the model to a file using the EMFModelManager.
     void saveState(IMemento memento)
              Closes all views of this editor.
     void selectionChanged(IWorkbenchPart part, ISelection selection)
               
     void setFocus()
               
    protected  void setInput(IEditorInput input)
              This method will create an EMFModelManager that handles loading and saving to the file the passed IEditorInput relies on.
    protected abstract  void setupKeyHandler(KeyHandler kh)
              Subclasses must implement to associate KeyStrokes with Actions in the passed KeyHandler which is the one used for the MuvitorTreeEditor.EditorTreeViewer.
    static IViewPart showView(EObject model)
              This is Muvitor's main method for opening a MuvitorPageBookView in the workbench displaying a model.
    protected static IViewPart showView(String viewId, EObject model)
              This method does the actual work of opening a MuvitorPageBookView .
    protected  void updateActions()
              Updates all UpdateActions registered in the actionRegistry.
     
    Methods inherited from class org.eclipse.ui.part.EditorPart
    checkSite, getEditorInput, getEditorSite, getTitleToolTip, isSaveOnCloseNeeded, setContentDescription, setInitializationData, setInputWithNotify, setPartName
     
    Methods inherited from class org.eclipse.ui.part.WorkbenchPart
    addPartPropertyListener, addPropertyListener, firePartPropertyChanged, getConfigurationElement, getContentDescription, getDefaultImage, getOrientation, getPartName, getPartProperties, getPartProperty, getSite, getTitle, getTitleImage, removePartPropertyListener, removePropertyListener, setPartProperty, setSite, setTitle, setTitleImage, setTitleToolTip, showBusy
     
    Methods inherited from class org.eclipse.core.commands.common.EventManager
    addListenerObject, clearListeners, getListeners, isListenerAttached, removeListenerObject
     
    Methods inherited from class java.lang.Object
    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
     
    Methods inherited from interface org.eclipse.ui.IWorkbenchPart
    addPropertyListener, getSite, getTitle, getTitleImage, removePropertyListener
     

    Field Detail

    fileExtension

    public static final String fileExtension
    The file extension this editor reacts on as specified in plugin.xml

    Constructor Detail

    MuvitorTreeEditor

    protected MuvitorTreeEditor()
    The standard constructor creates a DefaultEditDomain and registers itself as a CommandStackListener on the domains CommandStack.

    Throws:
    PartInitException
    Method Detail

    setInput

    protected final void setInput(IEditorInput input)
    This method will create an EMFModelManager that handles loading and saving to the file the passed IEditorInput relies on. If loading fails (possibly because we created a file with the creation wizard) we create a new default model and put it to the file resource.

    Overrides:
    setInput in class EditorPart
    See Also:
    createDefaultModel(), EditorPart.setInput(org.eclipse.ui.IEditorInput)

    createDefaultModel

    protected abstract EObject createDefaultModel()
    Subclasses have to generate a default model in this method. This will be called if loading from a file fails. For separate model roots override createDefaultModels() instead and leave this method implementation empty.

    Returns:
    the default model
    See Also:
    setInput(IEditorInput)

    createDefaultModels

    protected List<EObject> createDefaultModels()
    By default, MuvitorTreeEditor uses a single model root, which will be created in createDefaultModel(). But it is capable to handle multiple roots

    Returns:

    commandStackChanged

    public final void commandStackChanged(EventObject event)
    When the command stack changes, the actions are updated. Additionally the editor checks if itself has changed its dirty state by comparing its previous dirty state with the actual command stack state.

    Specified by:
    commandStackChanged in interface CommandStackListener
    Parameters:
    event - the change event

    registerAction

    protected final IAction registerAction(IAction action)
    Registers the action with the editor's action registry.

    There is no need to set handles that you register here (which will be used if the TreeEditor is the active part) for the RetargetActions here because this will be done by default in ActionBarContributor.setActiveEditor(IEditorPart). This will work as long as the handle action has the same ID as the RetargetAction it is meant to handle.

    Keep in mind that RetargetAction handles for MuvitorPages must be set explicitly! See there for more information about registering (shared) handles for RetargetActions.

    Parameters:
    action - the action to be registered in this editor's ActionRegistry

    registerActionOnToolBar

    protected final IAction registerActionOnToolBar(IAction action)
    Registers the action with the editor's action registry and puts it on this editor's tool bar.

    With this, you will rarely need to create RetargetActions. But if you do, use (subclass) MuvitorActionBarContributor for this purpose and check it and createActions() for existing actions before.

    Parameters:
    action - the action to be registered in this editor's ActionRegistry and to be put on the editors tool bar.
    See Also:
    registerAction(IAction)

    createCustomActions

    protected abstract void createCustomActions()
    To be implemented by subclasses.

    To be available for the context menu, tool bar, key binding, or as shared action instance for this editor's MuvitorPages (see there for information about sharing action instances), custom actions have to registered here via registerAction(IAction). Alternatively, you may use the convenient method registerActionOnToolBar(IAction) to put an action on a tool bar.
    With this, you will rarely need to create RetargetActions. But if you do, use (subclass) MuvitorActionBarContributor for this purpose and check it and createActions() for existing actions before.

    WorkbenchPartActions and SelectionActions created here should get the editor (this) as workbench part in their constructor.

    There is no need to set handles that you create here (which will be used if the TreeEditor is the active part) for the RetargetActions here because this will be done by default in ActionBarContributor.setActiveEditor(IEditorPart). This will work as long as the handle action has the same ID as the RetargetAction it is meant to handle.

    Keep in mind that RetargetAction handles for MuvitorPages must be set explicitly! See there for more information about registering (shared) handles for RetargetActions.

    See Also:
    createActions(), createContextMenuProvider(TreeViewer), MuvitorActionBarContributor

    createPartControl

    public final void createPartControl(Composite parent)
    Realizes the editor by creating its Control. The tree viewer is added to the SelectionSynchronizer, which can be used to keep 2 or more EditPartViewers in sync. The viewer is also registered as the ISelectionProvider for the Editor's PartSite. The editor again registers itself as a listener to the global selection service to react on changes in this plugin's MuvitorPageBookViews.

    WARNING: This method may or may not be called by the workbench prior to dispose().

    Specified by:
    createPartControl in interface IWorkbenchPart
    Specified by:
    createPartControl in class WorkbenchPart
    Parameters:
    parent - the parent composite
    See Also:
    org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets .Composite)

    dispose

    public void dispose()
    Tries to close views for all models of the resource that have possibly been opened. Stops listening to the command stack and selection service. Closes the perspective if the last editor instance is being closed. Subclasses may override but must call super implementation!

    Specified by:
    dispose in interface IWorkbenchPart
    Overrides:
    dispose in class WorkbenchPart

    firePropertyChange

    protected final void firePropertyChange(int property)
    Overrides:
    firePropertyChange in class WorkbenchPart

    getPrimaryModelRoot

    public EObject getPrimaryModelRoot()
    Returns by default the first model in the list of EObject models that have been loaded by the EMFModelManager. This will be set as contents for the TreeViewer. Subclasses may override.

    Returns:
    the element of the model roots to be set as the treeviewer's contents
    See Also:
    getModelRoots()

    getModelRoots

    public final List<EObject> getModelRoots()
    Returns the list of EObject models that have been loaded by the EMFModelManager. The first of this (see getPrimaryModelRoot()) will be set as contents for the TreeViewer.

    Returns:
    the modelRoots of this editor

    getActionRegistry

    protected final ActionRegistry getActionRegistry()
    Lazily creates, initializes and returns the action registry. The keyhandler will be configured with custom key bindings here.

    Returns:
    the action registry
    See Also:
    createActions(), updateActions()

    getKeyHandler

    protected final KeyHandler getKeyHandler()
    Need to create key handler lazily because accessing the action registry creates the actions which needs the editor site etc.

    Returns:
    the lazily created keyhandler with default key strokes

    getAdapter

    public Object getAdapter(Class type)
    IMPORTANT certain requests, such as the property sheet, may be made before or after createPartControl(Composite) is called. The order is unspecified by the Workbench. Subclasses may override but must call super implementation!

    Specified by:
    getAdapter in interface IAdaptable
    Overrides:
    getAdapter in class WorkbenchPart
    See Also:
    IAdaptable.getAdapter(java.lang.Class)

    getCommandStack

    protected final CommandStack getCommandStack()
    Returns:
    this editor's command stack

    getEditDomain

    protected final DefaultEditDomain getEditDomain()
    Returns:
    this editor's edit domain

    getTreeViewer

    public final TreeViewer getTreeViewer()
    Returns:
    The MuvitorTreeEditor.EditorTreeViewer in this editor.

    getStatusLineManager

    public final IStatusLineManager getStatusLineManager()
    This can be used to display messages in this page's status line.

    Returns:
    The IStatusLineManager from the IActionBars of this page's IPageSite

    init

    public void init(IEditorSite site,
                     IEditorInput input)
    Sets the site and input for this editor and opens the unique perspective defined in plugin.xml. Subclasses may extend this method but must call super implementation!

    Specified by:
    init in interface IEditorPart
    Specified by:
    init in class EditorPart
    See Also:
    IEditorPart.init(IEditorSite, IEditorInput)

    setupKeyHandler

    protected abstract void setupKeyHandler(KeyHandler kh)
    Subclasses must implement to associate KeyStrokes with Actions in the passed KeyHandler which is the one used for the MuvitorTreeEditor.EditorTreeViewer.

    See Also:
    getKeyHandler()

    createContextMenuProvider

    protected abstract ContextMenuProviderWithActionRegistry createContextMenuProvider(TreeViewer viewer)
    Subclasses must implement to specify the ContextMenuProviderWithActionRegistry that should be used by this editor's MuvitorTreeEditor.EditorTreeViewer and is responsible to show the created actions in the context menu.

    Parameters:
    viewer - The graphical viewer for context menu provider
    Returns:
    The ContextMenuProviderWithActionRegistry for the specified MuvitorTreeEditor.EditorTreeViewer.
    See Also:
    createTreeViewer(Composite)

    createTreeEditPartFactory

    protected abstract EditPartFactory createTreeEditPartFactory()
    Subclasses must implement this to specify the EditPartFactory that should be used by this editor's MuvitorTreeEditor.EditorTreeViewer.

    Returns:
    The EditPartFactory for the GEF MuvitorTreeEditor.EditorTreeViewer.

    isDirty

    public final boolean isDirty()
    Returns true if the command stack is dirty

    Specified by:
    isDirty in interface ISaveablePart
    Specified by:
    isDirty in class EditorPart
    See Also:
    ISaveablePart.isDirty()

    setFocus

    public final void setFocus()
    Specified by:
    setFocus in interface IWorkbenchPart
    Specified by:
    setFocus in class WorkbenchPart

    updateActions

    protected final void updateActions()
    Updates all UpdateActions registered in the actionRegistry.


    isSaveAsAllowed

    public final boolean isSaveAsAllowed()
    Specified by:
    isSaveAsAllowed in interface ISaveablePart
    Specified by:
    isSaveAsAllowed in class EditorPart

    doSave

    public final void doSave(IProgressMonitor monitor)
    Specified by:
    doSave in interface ISaveablePart
    Specified by:
    doSave in class EditorPart

    doSaveAs

    public final void doSaveAs()
    Specified by:
    doSaveAs in interface ISaveablePart
    Specified by:
    doSaveAs in class EditorPart

    selectionChanged

    public final void selectionChanged(IWorkbenchPart part,
                                       ISelection selection)
    Specified by:
    selectionChanged in interface ISelectionListener

    save

    protected void save(IFile file,
                        IProgressMonitor monitor)
                 throws CoreException
    This method saves the model to a file using the EMFModelManager. Subclasses may extend but must call super implementation!

    Parameters:
    file - The IFile to save the model to.
    progressMonitor - A progress monitor that could be used to show the saving status.
    Throws:
    CoreException - This exception indicates that something went wrong during saving.

    registerViewID

    public static final void registerViewID(EClass eClass,
                                            String viewID)
    Associate a class of models with the ID of a MuvitorPageBookView that has been registered in plugin.xml.

    Parameters:
    modelClass - a class of EObjects
    viewID - the ID of a view to show the class of EObjects
    See Also:
    showView(EObject)

    showView

    public static final IViewPart showView(EObject model)
    This is Muvitor's main method for opening a MuvitorPageBookView in the workbench displaying a model. It will check if the EClass of the passed model or of one of its ancestors has been registered with a view ID via registerViewID(EClass, String) and will open a view of this type showing the corresponding model. *

    If a view can be opened successfully it will be returned.

    Parameters:
    model - The model to be shown in the view
    Returns:
    the view part that has been opened or null
    See Also:
    showView(String, EObject)

    showView

    protected static final IViewPart showView(String viewId,
                                              EObject model)
    This method does the actual work of opening a MuvitorPageBookView . An unique ID for the passed model is being created and set as secondary ID of the new view. The model for this ID will be resolved y the view via IDUtil.

    If a view can be opened successfully it will be returned.

    In the special case that Eclipse has just been started and there is not an active IWorkbenchPage the opening of the view will be delayed to when the IWorkbenchWindow is being activated. So, this method will return null, even if the view might be opened successfully later.

    Parameters:
    viewId - The primary ID of the view to be opened. This must correspond to an org.eclipse.ui.views entry in plugin.xml
    model - The model to be shown in the view
    Returns:
    the view part that has been opened or null

    closeViewShowing

    public static final void closeViewShowing(EObject model)
    This is Muvitor's main method for closing a view in the workbench showing a specific EObject. This is the view that has been opened with showView(EObject) for this model.


    closeViews

    public static final ArrayList<EObject> closeViews(MuvitorTreeEditor editor)
    Similar to closeViewShowing(EObject) this method closes all views showing an EObject that belongs to the specified editor, according to IDUtil.getHostEditor(EObject).

    Parameters:
    editor - the editor whose views should be closed
    Returns:
    a list of the EObjects that were shown in the closed views

    saveState

    public void saveState(IMemento memento)
    Closes all views of this editor. The model URIs for the currently open views are stored to the editor's IMemento.
    To be called, when the editor is being closed. Subclasses may extend but must call super implementation!

    Specified by:
    saveState in interface IPersistable
    See Also:
    restoreState(IMemento), IPersistable.saveState(org.eclipse.ui.IMemento)

    restoreState

    public void restoreState(IMemento memento)
    Restores the views that were opened when Eclipse was closed during an editor session if the editor is still able to work on the same file. Subclasses may extend but must call super implementation!

    Specified by:
    restoreState in interface IPersistableEditor
    See Also:
    saveState(IMemento), IPersistableEditor.restoreState(org.eclipse.ui.IMemento)

    revertToLastSaved

    public void revertToLastSaved()
    This method implements support for the Muvitor's RevertAction. Subclasses may extend but must call super implementation! Closes all views, resets the actual input, and updates all actions.


    createErrorMarker

    public final IMarker createErrorMarker(EObject model,
                                           String location,
                                           String message)
    Create an eclipse error marker for the currently edited file on given location with specified message. An EObject model's ID will be stored with in this marker, allowing MuvitorTreeEditor to "jump" to the error-causing model via gotoMarker(IMarker).

    Parameters:
    model - an EObject model as the problem cause
    location - the location of the problem
    message - a message describing the problem
    Returns:
    the newly created marker for setting further attributes
    See Also:
    gotoMarker(IMarker)

    findProblemMarkers

    public final ArrayList<IMarker> findProblemMarkers(String attrName)
    Convenience method that collects all problem markers like findProblemMarkers(String, Object) for which the attribute has been set with any value.

    Parameters:
    attrName - some custom attribute that has been set to a marker
    Returns:
    a list of problem markers for the currently opened file for which the attribute has been set with any value

    findProblemMarkers

    public final ArrayList<IMarker> findProblemMarkers(String attrName,
                                                       Object attrValue)
    Helper method to find problem markers with specific attribute values. The main purpose is to to allow checking facilities to manage (especially delete) problem markers they have created.

    Parameters:
    attrName - some custom attribute that has been set to a marker
    attrValue - a value for the attrName attribute to be matched; will be ignored if null
    Returns:
    a list of problem markers for the currently opened file with the specified attribute values

    gotoMarker

    public void gotoMarker(IMarker marker)
    This default implementation of IGotoMarker tries to resolve the marker's IMarker.SOURCE_ID attribute to an EObject model. If such a model exists it will be opened via showView(EObject) (if possible) and set as the selection in the corresponding viewer.

    Specified by:
    gotoMarker in interface IGotoMarker
    See Also:
    org.eclipse.ui.ide.IGotoMarker#gotoMarker(org.eclipse.core.resources. IMarker), createErrorMarker(EObject, String, String)