RSS

Search Engine

Saturday, October 23, 2010

Contribute model elements via plugins

13.1. Contribute a model elements

Eclipse e4 allows that model elements are contributed to the base model (from Applicatin.e4xmi) via the extension point "org.eclipse.e4.workbench.model". Model elements can be contributed via "fragments" or via "processors". A fragment is a xmi file which specifies additional model elements. A processor allows to contribute to the model via program code, e.g. in situations where the model contributions are dynamic. A model fragment is similar to the existing extension mechanism of Eclipse 3.x but is based on the Eclipse 4.0 extension mechanism. A processor allows the dynamic creation of model elements thus giving the developer much more flexibility.

If you want to contribute to a base model via fragments you always specify to which element you are contributing. Therefore this element you are contributing to must have its ID specified.

13.2. Create new plugin

Create a plugin "sawan.modi.e4.todo.contribute" without any templates. Add a dependency to "org.eclipse.e4.ui.workbench" and add the extension point "org.eclipse.e4.workbench.model".

You may need to import the "org.eclipse.e4.workbench.model" from git to make this extension point work for you. See also Bug report .

13.3. Contributing via processors

It is possible to contribute via processors, e.g. Java code which creates and modify model elements. In the following example we will replace the exiting menu entry in our e4 todo application and add a new entry in the menu.

In your plugin "sawan.modi.e4.todo.contribute" add a "processor" for the "org.eclipse.e4.workbench.model" extension point.

The parameter will be the model element which is can later inject into our Java class.

Create the following dialog and handler class. The handler will later be used in the new menu entry.

    
package sawan.modi.e4.todo.contribute;

import javax.inject.Inject;
import javax.inject.Named;

import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class ExitDialog extends Dialog {
@Inject
public ExitDialog(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell) {
super(shell);
}

@Override
protected Control createDialogArea(Composite parent) {
Label label = new Label(parent, SWT.NONE);
label.setText("Closing this application may result in data loss. Are you sure you want that");
return parent;
}

}

    
package sawan.modi.e4.todo.contribute.handler;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.workbench.IWorkbench;
import org.eclipse.jface.window.Window;

import sawan.modi.e4.todo.contribute.ExitDialog;

public class ExitHandlerWithCheck {
@Execute
public void execute(IEclipseContext context, IWorkbench workbench) {
ExitDialog dialog = ContextInjectionFactory.make(ExitDialog.class, context);
dialog.create();
if (dialog.open() == Window.OK) {
workbench.close();
}
}
}

Create now the model processor class.

    
package sawan.modi.e4.todo.contribute;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;

import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.model.application.ui.menu.MDirectMenuItem;
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory;

public class MenuProcessor {
// I get this via the parameter of the process definition
@Inject
@Named("sawan.modi.e4.todo.filemenu")
private MMenu menu;

@Execute
public void execute() {
// Remove the old exit menu entry
if (menu != null && menu.getChildren() != null) {
List list = new ArrayList();
for (MMenuElement element : menu.getChildren()) {
if (element.getLabel().contains("Exit")) {
list.add(element);
}
}
menu.getChildren().removeAll(list);
}
// Now add a new menu entry
MDirectMenuItem menuItem = MMenuFactory.INSTANCE.createDirectMenuItem();
menuItem.setLabel("Another Exit");
menuItem.setContributionURI("platform:/plugin/sawan.modi.e4.todo.contribute/sawan.modi.e4.todo.contribute.handler.ExitHandlerWithCheck");
menu.getChildren().add(menuItem);
}
}

Add this plugin to your product and run your product. The old exit menu entry should be removed and you should see the new menu entry.

0 comments:

Post a Comment