Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding figures using contextual menu - Eclipse GEF

All,

I am creating a palette less eclipse plugin where am adding figures to the custom editor through the contextual menu, but am not finding a way to do it. Can anyone please guide me as to how to go about adding figures to editor dynamically through context menu i.e. adding actions/commands.


Since Eclipse GEF plugin development finds so less examples to look at, I am adding my solution so others find it useful. This code helps to render a node to the editor.

Source code for Action class to render figures to the editor:

public class AddNodeAction extends EditorPartAction
{
 public static final String ADD_NODE = "ADDNODE";

 public AddNodeAction(IEditorPart editor) {
  super(editor);
            setText("Add a Node");
            setId(ADD_NODE);     // Important to set ID
 }

 public void run()
 {
  <ParentModelClass> parent=  (<ParentModelClass>)getEditorPart().getAdapter(<ParentModelClass>.class);

  if (parent== null)
   return;
  CommandStack command = (CommandStack)getEditorPart().getAdapter(CommandStack.class);

  if (command != null)
  {
   CompoundCommand totalCmd = new CompoundCommand();
   <ChildModelToRenderFigureCommand>cmd = new <ChildModelToRenderFigureCommand>(parent);
   cmd.setParent(parent);
   <ChildModelClass> newNode = new <ChildModelClass>();
   cmd.setNode(newNode);
   cmd.setLocation(getLocation()); // Any location you wish to set to
   totalCmd.add(cmd);
   command.execute(totalCmd);
  }
 }

 @Override
 protected boolean calculateEnabled() 
 {
  return true;
 }
}
like image 876
name_masked Avatar asked Dec 24 '10 17:12

name_masked


1 Answers

I think you need multiple different things here. Please remember that GEF would like you to have proper MVC pattern, where you have your own model, Figures as View and EditParts as controllers.

From the top of my head I would say that you need at least these things:

  • CreateCommand
    • contains all model level modifications that you need to perform to add your new data to your data model (undoable and transactional)
  • CreateAction
    • makes that CreateCommand instance, initializes it with current selection and executes that command in editdomain
  • ContextMenuProvider
    • Provides that CreateAction to context menu

If you happen to be using GMF the canonical mechanism will generate the editparts for you automatically when you make the model modifications inside a command, but if you are not using GMF, you must make sure that your own models and editparts are handling and refreshing the new item adding properly.

EDIT: Ok, here is some code suggestion with playing around with requests.

public void run() {
   // Fetch viewer from editor part (might not work, if not, try some other way)
   EditPartViewer viewer = (EditPartViewer) part.getAdapter(EditPartViewer.class);
   // get Target EditPart that is under the mouse
   EditPart targetEditPart = viewer.findObjectAt(getLocation());
   // If nothing under mouse, set root item as target (just playing safe)
   if(targetEditPart == null)
       targetEditPart = viewer.getContents();

   // Make and initialize create request with proper information
   CreateRequest createReq = new CreateRequest();
   createReq.setLocation(getLocation());
   createReq.setFactory(new OwnFactoryImplementation());

   // Ask from target editpart command for this request
   Command command = targetEditPart.getCommand(createReq);

   // If command is ok, and it can be executed, go and execute it on commandstack
  if(command != null && command.canExecute()) {
      viewer.getEditDomain().getCommandStack().execute(command);
  }
}

Now what happens is that editpart will be requested for creation, so the action itself doesn't know how the command works, what makes it objective agaist the command.

So to make things work, you need to install new EditPolicy to your EditPart. EditPolicies can be installed on EditParts createDefaultEditPolicies() function. This EditPolicy must react and return command when there is CreateRequest. This way any child can provide own kind of command for creating children for itself.

Here is a good image how it works (controller is EditPart): Diagram

Please ask if I can help you some more. I know that this looks bit more complex, but this makes your own life much more easier, and after you have done that, you actually understand Command-Request Pattern quite well, and it can be reused in many different places.

like image 57
Tuukka Lindroos Avatar answered Oct 26 '22 01:10

Tuukka Lindroos