Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » GMF (Graphical Modeling Framework) » Generating palette programmatically
Generating palette programmatically [message #731284] Fri, 30 September 2011 14:08 Go to next message
Neslepaks  is currently offline Neslepaks
Messages: 37
Registered: April 2011
Member
Hi,

I would need to dynamically change palette so I am trying to programmatically generate one. I am doing this with Papyrus if it matters at all.

The following code example shows what I have successfully done: A new drawer to palette with one tool.

// Some code to reach the editor.
		ServicesRegistry serviceRegistry;
		ISashWindowsContainer container;
		try {
			serviceRegistry = ServiceUtilsForActionHandlers.getInstance().getServiceRegistry();
			container = ServiceUtils.getInstance().getISashWindowsContainer(serviceRegistry);
		} catch (ServiceException e) {

			e.printStackTrace();
			return;	
		}  

		// Get editor.
		IEditorPart activeEditor = container.getActiveEditor();			
		DiagramEditorWithFlyOutPalette dewfop = (DiagramEditorWithFlyOutPalette) 
				((DiagramEditorWithFlyOutPalette) activeEditor);

		// Create a new drawer
		PaletteDrawer pd = new PaletteDrawer("New Drawer");
		PaletteRoot pr = dewfop.getDiagramGraphicalViewer().getEditDomain().getPaletteViewer().getPaletteRoot();
		pr.add(pd);

		// Add a new tool to drawer
		//PaletteFactory pf = PaletteFactory.Adapter
		PaletteToolEntry entry = new PaletteToolEntry("label", "Tool", null); //What to do with the third parameter?
		pd.add(entry);


1. PaletteToolEntry's constructor's third parameter should be PaletteFactory. How do I pass that argument?

2. How it is possible to determine that the new entry should create, for example, Package with stereotype "PackageStereotype"?
Re: Generating palette programmatically [message #733524 is a reply to message #731284] Tue, 04 October 2011 23:40 Go to previous messageGo to next message
Michael Golubev is currently offline Michael Golubev
Messages: 373
Registered: July 2009
Senior Member
Hello,

I was sure Papyrus already has code to modify palette when the profile is defined -- for every stereotype you should get the additional tool that creates the instance with this stereotype applied.

I wrote something very similar 4 years ago but can't find it now.

Anyway, I would have it implemented by contributing the custom IPaletteProvider, as explained at the tutorial here.

This new provider in the contributeToPalette method would check whether it should add custom content by checking your specific properties of passed 'editor' and 'content' parameters.

I never used the PaletteToolEntry and subclasses before, so here is how I would do that without them:
//in the MyPaletteProvider class: 
	private ToolEntry createSubmachineState3CreationTool() {
		Stereotype someStereo = myFindSomeStereotypeToApply();
		List<IElementType> types = myComputeListOfApplicableElementTypes();
		MyToolEntry entry = new MyToolEntry(types, someStereo);
		entry.setId(...);
		entry.setSmallIcon(...);
		entry.setLargeIcon(...);
		entry.setToolClass(CreateSubmachineStateTool.class);
		return entry;
	}

	private static class MyToolEntry extends ToolEntry {

		private final List<IElementType> myElementTypes;

		private final Stereotype myStereo;

		public MyToolEntry(List<IElementType> elementTypes, Stereotype stereo) {
			super("Label", "Desc", null, null);
			myElementTypes = elementTypes;
			myStereo = stereo;
		}

		@Override
		public Tool createTool() {
			return new MyWithStereotypeTool(myElementTypes, myStereo);
		}

	}

	private static class MyWithStereotypeTool extends UnspecifiedTypeCreationTool {

		public static final String PROP_NAME = "StereotypeToAdd";

		private final Stereotype myUmlStereo;

		public MyWithStereotypeTool(List<IElementType> elementTypes, Stereotype umlStereo) {
			super(elementTypes);
			myUmlStereo = umlStereo;
		}

		@Override
		protected Request createTargetRequest() {
			CreateUnspecifiedTypeRequest request = (CreateUnspecifiedTypeRequest) super.createTargetRequest();
			//below is the only way to propagate extended data into IEditCommandRequest#parameters  
			HashMap extendedData = new HashMap();
			extendedData.putAll(request.getExtendedData());
			extendedData.put(PROP_NAME, myUmlStereo);
			request.setExtendedData(extendedData);
			return request;
		}
	}


The code to handle the request from new custom tool looks like this:

	//somewhere in XXXElementHelper
	protected ICommand getConfigureCommand(final ConfigureRequest req) {
		if (req.getParameter(MyWithStereotypeTool.PROP_NAME) instanceof Stereotype) {
			return new AbstractTransactionalCommand(req.getEditingDomain(), "Applying the stereo", null) {
				@Override
				protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
					Stereotype applyMe = (Stereotype)req.getParameter(MyWithStereotypeTool.PROP_NAME);
					customApplyUMLStereotype(req.getElementToConfigure(), applyMe);
					return CommandResult.newOKCommandResult();
				}
			};
		}
		return null;
	}


Also there should be a code in the editor that clears the old palete and creates a new one like this;
//in the diagram editor: 
	public void refreshPalette() {
		PaletteRoot paletteRoot = getEditDomain().getPaletteViewer().getPaletteRoot();
		cleanPaletteRoot(paletteRoot);
		createPaletteRoot(paletteRoot);
	}

	private void cleanPaletteRoot(PaletteRoot paletteRoot) {
		List<Object> entries = new ArrayList<Object>();
		entries.addAll(paletteRoot.getChildren());
		for (Object entry : entries) {
			PaletteEntry paletteEntry = (PaletteEntry) entry;
			// we don't repaint standard palette group
			if (PaletteService.GROUP_STANDARD.equals(paletteEntry.getId())) {
				continue;
			}
			paletteRoot.remove(paletteEntry);
		}
	}



and finally, somewhere in the place where you know that the palette need to be changed (e.g, inthe Profile application action):

		XXXDiagramEditor editop = reachTheEditor(...);
		editor.refreshPalette();


Hope it helps,
Regards,
Michael "Borlander" Golubev
Eclipse Committer (GMF, UML2Tools)
at Montages Think Tank, Prague, Czech Republic
Montages AG, Z├╝rich, Switzerland
Re: Generating palette programmatically [message #734285 is a reply to message #733524] Fri, 07 October 2011 11:36 Go to previous message
Neslepaks  is currently offline Neslepaks
Messages: 37
Registered: April 2011
Member
Thanks for the wide and helpful answer.

Still I managed to solve problem by using a kind of detour.

Creating the palette:
	// Get editor.
		IEditorPart activeEditor = container.getActiveEditor();			
		DiagramEditorWithFlyOutPalette dewfop = (DiagramEditorWithFlyOutPalette) 
				((DiagramEditorWithFlyOutPalette) activeEditor);

		// Create a new drawer
		PaletteDrawer pd = new PaletteDrawer("My drawer");
		PaletteRoot pr = dewfop.getDiagramGraphicalViewer().getEditDomain().getPaletteViewer().getPaletteRoot();
		pr.add(pd);

		// Add a new tool kit to drawer
		List<CreationToolEntry> cteList = new ArrayList();
		for(int i = 0; i < MyDatabase.size(); ++i)
		{
			CreationToolEntry cte = new CreationToolEntry("New Tool" + i, "Add new ...", new MyCreationFactory(Class.class, MyDatabase.get(i).getName(), MyDatabase, window), null, null);
			cteList.add(cte);
		}

		pd.addAll(cteList); // add all the new tools


Then the creation of the new element on diagram is implemented in the function getNewObject() in MyCreationFactory which implements CreationFactory. For creating the element, I used the way I demonstrated here: http://www.eclipse.org/forums/index.php/mv/msg/220362/717730/#msg_717730. Therefore the getNewObject returns just some irrelevant stuff.

Applying the stereotype for the created element is done in the way as described in this thread:
http://www.eclipse.org/forums/index.php/t/236230/

For the drag&drop-functionality I used this(http://www.eclipse.org/forums/index.php/m/649784/) kind of method to get the drop location.

This is not the "proper" way to use CreationFactory and Palette but it is enough for my needs at this point. At least one disadventage is that the mouse pointer shows "stop" sign on the canvas. Maybe this is related to the policies? Maybe there is a way to force the mouse pointer to some other icon.
Previous Topic:XYAnchor to EllipseAnchor: is it possible?
Next Topic:Second Palette for DiagramEditor
Goto Forum:
  


Current Time: Wed Sep 24 00:43:36 GMT 2014

Powered by FUDForum. Page generated in 0.01794 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software