I'm using a MenuContribution to feed a menu entry, implementing a feature like the "switch workspace" in E3. In a dynamic menu contribution, i'm building a 3 item list of most recent opened projects followed by the "Other.." entry. graphically, i'm done, the 3 list, separator and "other.." menu elements are showing up.
But in the case of most recent project, i have to dynamically pass the project name/Path to the handler which consume the selection event. below is a code similar to what i have in the menu contribution that creates one of the 3 recent project item :
@AboutToShow
public void aboutToShow(List<MMenuElement> items, MApplication application) {
MHandledMenuItem dynamicItem = modelService.createModelElement(MHandledMenuItem.class);
dynamicItem.setLabel(projectName);
dynamicItem.setContributorURI("platform:/plugin/com.acme");
MCommand command = modelService.createModelElement(MCommand.class);
command.setElementId(LOAD_PROJECT_COMMAND_ID);
MCommandParameter commandParam = modelService.createModelElement(MCommandParameter.class);
commandParam.setElementId(PROJECT_NAME_PARAMETER_ID);
commandParam.setName(PROJECT_NAME_PARAMETER_ID);
command.getParameters().add(commandParam);
// one of the 3 last used projects
String projectName = "foo";
dynamicItem.setCommand(command);
items.add(dynamicItem);
}
where LOAD_PROJECT_COMMAND_ID and PROJECT_NAME_PARAMETER_ID are e4xmi command and command parameter id. I wonder how i can put projectName in the command to be able to get it back in the associated handler, which contains something like :
@Execute
public void execute(ParameterizedCommand command) {
[...]
}
Note : I read Lars tutorial about menus but did not found solution in there
--- EDIT : full contribution code ---
import java.util.Collections;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.eclipse.e4.core.commands.ECommandService;
import org.eclipse.e4.ui.di.AboutToShow;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.commands.MCommand;
import org.eclipse.e4.ui.model.application.commands.MParameter;
import org.eclipse.e4.ui.model.application.ui.menu.MDirectMenuItem;
import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuSeparator;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import com.acme.model.platypus.extractionresult.CampaignResultProvider;
@SuppressWarnings("restriction")
public class SwitchProjectMenuContribution {
private static final String NEW_PROJECT = "Other...";
private static final String LOAD_PROJECT_COMMAND_ID = "gui.rcp4.command.loadProjectCommand";
private static final String PROJECT_NAME_PARAMETER_ID = "gui.rcp4.command.loadProjectCommand.projectName";
@Inject
CampaignResultProvider campaignResultProvider;
@Inject
private EModelService modelService;
@Inject
ECommandService commandService;
private MDirectMenuItem otherProjectItem;
private MMenuSeparator separatorItem;
private MCommand loadProjectCommand;
@SuppressWarnings("unchecked")
@PostConstruct
public void initialize(MApplication application) {
loadProjectCommand = (MCommand) modelService
.findElements(application, LOAD_PROJECT_COMMAND_ID, MCommand.class, Collections.EMPTY_LIST).get(0);
otherProjectItem = modelService.createModelElement(MDirectMenuItem.class);
otherProjectItem.setLabel(NEW_PROJECT);
otherProjectItem.setContributorURI("platform:/plugin/com.acme.gui.rcp4");
otherProjectItem.setContributionURI(
"bundleclass://com.acme.gui.rcp4/com.acme.gui.rcp4.handlers.OtherProjecthandler");
separatorItem = modelService.createModelElement(MMenuSeparator.class);
}
@AboutToShow
public void aboutToShow(List<MMenuElement> items, MApplication application) {
String[] lastProject = campaignResultProvider.getLastUsed();
MMenuElement newEntry;
for (String projectName : lastProject) {
newEntry = createExistingProjectEntry(projectName);
items.add(newEntry);
}
if (lastProject.length > 0) {
items.add(separatorItem);
}
items.add(otherProjectItem);
}
private MHandledMenuItem createExistingProjectEntry(String projectPath) {
MHandledMenuItem dynamicItem = modelService.createModelElement(MHandledMenuItem.class);
dynamicItem.setLabel(projectPath);
dynamicItem.setContributorURI("platform:/plugin/com.acme.gui.rcp4");
MParameter commandParam = modelService.createModelElement(MParameter.class);
commandParam.setName("projectName");
commandParam.setElementId(PROJECT_NAME_PARAMETER_ID);
commandParam.setValue(projectPath);
dynamicItem.getParameters().add(commandParam);
dynamicItem.setCommand(loadProjectCommand);
return dynamicItem;
}
}
You add the parameter value to the MHandledMenuItem
not the command.
Use a MParameter
and call the setName
and setValue
methods to set the name (must match the parameter name in the command) and value (the project name in your case).
Add the MParameter
to the MHandledMenuItem.getParameters()
list.
Note: You should only define the command and command parameter once, not every time aboutToShow
is called (so that should probably be in the e4xmi file).