Skip to main content



      Home
Home » Modeling » GMF (Graphical Modeling Framework) » Custom action in generated editor
Custom action in generated editor [message #72373] Tue, 31 October 2006 18:58 Go to next message
Eclipse UserFriend
Originally posted by: zazo7.wp.pl

Hi there!

I was wondering if there is any way to access diagram data from a custom
action (implementing IAction)? I have GMF-generated editor for my domain
model. I would like to add simple action to it (to the menu bar) which
can edit opened diagram.

I've been looking for the solution almost all day. All I have is:

....
public class MyAction implements IAction {

public void run() {

IWorkbenchWindow workbenchWindow =
PlatformUI.getWorkbench().getActiveWorkbenchWindow();

IWorkbenchPage activePage = workbenchWindow.getActivePage();
IEditorPart activeEditor = activePage.getActiveEditor();
IEditorInput editorInput = activeEditor.getEditorInput();
....


Can anyone tell me if this is a right direction or a dead end?
I will appreciate any help.

Regards

Tommy
Re: Custom action in generated editor [message #72444 is a reply to message #72373] Wed, 01 November 2006 02:52 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: vcciubot.uwaterloo.ca

You have to cast your editorPart to a GEF GraphicalEditor.
From there you get the graphical viewer -> getContents() to get the
diagram edit part. If you call resolveSematicElement() on that edit part
you get the root model element of your diagram.

Note that you will have to use commands to manipulate the model. So
basically, wrap your normal EMF manipulations in an
AbstractTransactionalCommand. You can execute those with
OperationHistory.getOperationFactory().execute().

Here's an example (sorry it's verbose)

(1) plugin.xml

<extension point="org.eclipse.ui.popupMenus">
<objectContribution
adaptable="false"
id=" ca.uwaterloo.watform.bluenose2.diagram.ui.actions.Bluenose2A bstraction "
objectClass=" org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditP art ">
<action
label="Create Abstract Block"
class=" ca.uwaterloo.watform.bluenose2.diagram.ui.actions.CreateAbst ractBlockAction "
menubarPath="additions"
enablesFor="*"
id="Bluenose2AbstractBlockAction">
</action>
</objectContribution>
</extension>

(2) action code:

public class CreateAbstractBlockAction implements IObjectActionDelegate {


private IWorkbenchPart myPart;
private IStructuredSelection mySelection;
private EObject parentBlock;
private List childrenBlock;
private IGraphicalEditPart someEditPart;


public void setActivePart(IAction action, IWorkbenchPart targetPart) {
myPart = targetPart;
}


public void selectionChanged(IAction action, ISelection selection) {
mySelection = StructuredSelection.EMPTY;

action.setEnabled(false);
if (selection instanceof IStructuredSelection == false
|| selection.isEmpty()) {
return;
}

if (myPart instanceof Bluenose2DiagramEditor == false)
return;

mySelection = (IStructuredSelection) selection;
someEditPart = (IGraphicalEditPart) mySelection.getFirstElement();

//postpone complicated checks till later when it's run
action.setEnabled(true);

}


public void run(IAction action) {

ProgressMonitorDialog progressDialog = new ProgressMonitorDialog(myPart.getSite().getShell());

IRunnableWithProgress runnable = new IRunnableWithProgress() {

public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
/*
* selected eobjects
*/

monitor.beginTask("Creating abstract block", IProgressMonitor.UNKNOWN);

monitor.subTask("Checking the selected elements");


Set eobjects = new HashSet();

Iterator selIt = mySelection.iterator();
while (selIt.hasNext()) {
IGraphicalEditPart editPart = (IGraphicalEditPart) selIt.next();
EObject element = editPart.resolveSemanticElement();
if (element instanceof Block)
eobjects.add(element);
}


/*
* children
*/
childrenBlock = new LinkedList();

Iterator eIt = eobjects.iterator();
while (eIt.hasNext()) {
EObject element = (EObject) eIt.next();
if (eobjects.contains(element.eContainer()) == false)
childrenBlock.add(element);
}

/*
* all roots must be children block of the same block
*/
boolean flag = true;

parentBlock = null;
Iterator childrenIt = childrenBlock.iterator();
while (childrenIt.hasNext()) {
EObject block = (EObject) childrenIt.next();
//make sure it's a block
if (block instanceof Block == false) {
flag = false;
break;
}
//check all blocks have the same parent
if (parentBlock != null && block.eContainer() != parentBlock) {
flag = false;
break;
}

if (parentBlock == null)
parentBlock = block.eContainer();
}

if (flag == false) {
throw new InterruptedException();
}

monitor.subTask("Creating the abstract element");


View parentView = (View) someEditPart.getModel();
Diagram diagram = (Diagram) EMFCoreUtil.getContainer(parentView, NotationPackage.eINSTANCE.getDiagram());
String diagramID = ViewUtil.getIdStr(diagram);


AbstractTransactionalCommand createCommand = new CreateAbstractBlockCommand((Block) parentBlock, childrenBlock, diagramID);
try {
OperationHistoryFactory.getOperationHistory().execute(create Command, monitor, null);
} catch (ExecutionException e){
//ignore
}

}

};

try {
progressDialog.run(true, true, runnable);
} catch (Exception e) {
//nada
}

(3) the command

public class CreateAbstractBlockCommand extends AbstractTransactionalCommand {

private List blocks;

private Block parent;

private String diagramID;

private static String label = "Create Abstract Command";

public CreateAbstractBlockCommand(Block parent, List blocks,
String diagramID) {
super(TransactionUtil.getEditingDomain(parent), label, Collections
.singletonList(WorkspaceSynchronizer
.getFile(parent.eResource())));
this.blocks = blocks;
this.parent = parent;
this.diagramID = diagramID;
}

/**
* @return The two port ends of the connection
*/
protected CommandResult doExecuteWithResult(IProgressMonitor monitor,
IAdaptable info) throws ExecutionException {

AbstractBlock absBlock = B2CreationCommandUtil.createAbstractBlock(
parent, monitor);
absBlock.setDiagramID(diagramID);
absBlock.getConcreteBlocks().addAll(blocks);
createAbstractConnections(absBlock);

return CommandResult.newOKCommandResult(absBlock);

}

/**
* Configures the connections of the abstract block.
*/
protected void createAbstractConnections(AbstractBlock absBlock) {

/*
* get recursively the concrete ends represented by this block
*/
Set concEnds = new HashSet();
Stack toProcess = new Stack();

pushAll(toProcess, absBlock.getConcreteBlocks());

while (toProcess.isEmpty() == false) {
EObject element = (EObject) toProcess.pop();
if (element instanceof End)
concEnds.add(element);
pushAll(toProcess, element.eContents());
}

/*
* get connections going outside of the abstract block
*/
List outgoingCons = new LinkedList();
List incomingCons = new LinkedList();
Iterator concEndsIt = concEnds.iterator();
while (concEndsIt.hasNext()) {
End concEnd = (End) concEndsIt.next();
// outgoing
{
Iterator it = concEnd.getOutgoingConnections().iterator();
while (it.hasNext()) {
Connection con = (Connection) it.next();
if (concEnds.contains(con.getDst()) == false)
outgoingCons.add(con);
}
}
// incoming
{
Iterator it = concEnd.getIncomingConnections().iterator();
while (it.hasNext()) {
Connection con = (Connection) it.next();
if (concEnds.contains(con.getSrc()) == false)
incomingCons.add(con);
}
}
}

/*
* Create the abstract connections.
*/
Map concDstEndToAbsCon = new HashMap();
Map concDstEndToConcCon = new HashMap();
// outgoing connections
{
Iterator it = outgoingCons.iterator();
while (it.hasNext()) {
Connection con = (Connection) it.next();
End dstEnd = con.getDst();
if (concDstEndToAbsCon.containsKey(dstEnd) == false) {
AbstractConnection absCon = B2CreationCommandUtil
.createAbstractConnection(absBlock, dstEnd,
new NullProgressMonitor());
concDstEndToAbsCon.put(dstEnd, absCon);
concDstEndToConcCon.put(dstEnd, new LinkedList());
}
List concCons = (List) concDstEndToConcCon.get(dstEnd);
concCons.add(con);
}
}
//incoming connections
Map concSrcEndToAbsCon = new HashMap();
Map concSrcEndToConcCon = new HashMap();
{
Iterator it = incomingCons.iterator();
while (it.hasNext()) {
Connection con = (Connection) it.next();
End srcEnd = con.getSrc();
if (concSrcEndToAbsCon.containsKey(srcEnd) == false) {
AbstractConnection absCon = B2CreationCommandUtil
.createAbstractConnection(srcEnd, absBlock,
new NullProgressMonitor());
concSrcEndToAbsCon.put(srcEnd, absCon);
concSrcEndToConcCon.put(srcEnd, new LinkedList());
}
List concCons = (List) concSrcEndToConcCon.get(srcEnd);
concCons.add(con);
}
}

//add the abstract connections to the abstract block
//outgoing
{
Iterator it = concDstEndToAbsCon.keySet().iterator();
while (it.hasNext()) {
End dstEnd = (End) it.next();
AbstractConnection absCon = (AbstractConnection) concDstEndToAbsCon
.get(dstEnd);
List concCons = (List) concDstEndToConcCon.get(dstEnd);
absBlock.getOutgoingConnections().add(absCon);
absCon.getConcreteConnections().addAll(concCons);
}
}
//incoming
{
Iterator it = concSrcEndToAbsCon.keySet().iterator();
while (it.hasNext()) {
End srcEnd = (End) it.next();
AbstractConnection absCon = (AbstractConnection) concSrcEndToAbsCon
.get(srcEnd);
List concCons = (List) concSrcEndToConcCon.get(srcEnd);
absBlock.getIncomingConnections().add(absCon);
absCon.getConcreteConnections().addAll(concCons);
}
}

}

/**
* Push a list of elements onto a stack.
*
* @param stack
* @param list
*/
protected void pushAll(Stack stack, List list) {
Iterator it = list.iterator();
while (it.hasNext()) {
stack.push(it.next());
}
}

}


On Wed, 01 Nov 2006 00:58:04 +0100, zazo7 wrote:

> Hi there!
>
> I was wondering if there is any way to access diagram data from a custom
> action (implementing IAction)? I have GMF-generated editor for my domain
> model. I would like to add simple action to it (to the menu bar) which
> can edit opened diagram.
>
> I've been looking for the solution almost all day. All I have is:
>
> ...
> public class MyAction implements IAction {
>
> public void run() {
>
> IWorkbenchWindow workbenchWindow =
> PlatformUI.getWorkbench().getActiveWorkbenchWindow();
>
> IWorkbenchPage activePage = workbenchWindow.getActivePage();
> IEditorPart activeEditor = activePage.getActiveEditor();
> IEditorInput editorInput = activeEditor.getEditorInput();
> ...
>
>
> Can anyone tell me if this is a right direction or a dead end?
> I will appreciate any help.
>
> Regards
>
> Tommy
Re: Custom action in generated editor (very Similar Question) [message #73395 is a reply to message #72444] Thu, 02 November 2006 10:01 Go to previous messageGo to next message
Eclipse UserFriend
Hi,

i've got a question that is closely related to the question asked before
in this thread:

I managed to add an action to the popup-menu that comes by right-click
into the empty-diagram-window from the GMF-generated graphical Editor
(similar to the 'Load Resource...'-Action).

BUT what I really need is to extend the popup-menu that comes up by
right-click of a special nodeType in the diagram.

Could you please give me a hint how to obtain that kind of extension?

Thanks in advance

Alex Haag
Re: Custom action in generated editor (very Similar Question) [message #73465 is a reply to message #73395] Thu, 02 November 2006 10:21 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: vcciubot.uwaterloo.ca

In your object contribution, as seen in the the previous post, specify the
right type of the edit part corresponding to that node. So instead of
IGraphicalEditPart put the qualified name of your edit part.

vlad



On Thu, 02 Nov 2006 16:01:03 +0100, Alex Haag wrote:

> Hi,
>
> i've got a question that is closely related to the question asked before
> in this thread:
>
> I managed to add an action to the popup-menu that comes by right-click
> into the empty-diagram-window from the GMF-generated graphical Editor
> (similar to the 'Load Resource...'-Action).
>
> BUT what I really need is to extend the popup-menu that comes up by
> right-click of a special nodeType in the diagram.
>
> Could you please give me a hint how to obtain that kind of extension?
>
> Thanks in advance
>
> Alex Haag
Re: Custom action in generated editor [message #73643 is a reply to message #72444] Thu, 02 November 2006 18:46 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: zazo7.wp.pl

Vlad Ciubotariu wrote:
> You have to cast your editorPart to a GEF GraphicalEditor.
> From there you get the graphical viewer -> getContents() to get the
> diagram edit part. If you call resolveSematicElement() on that edit part
> you get the root model element of your diagram.
>
> Note that you will have to use commands to manipulate the model. So
> basically, wrap your normal EMF manipulations in an
> AbstractTransactionalCommand. You can execute those with
> OperationHistory.getOperationFactory().execute().
>
> Here's an example (sorry it's verbose)
>
> (1) plugin.xml
>
> <extension point="org.eclipse.ui.popupMenus">
> <objectContribution
> adaptable="false"
> id=" ca.uwaterloo.watform.bluenose2.diagram.ui.actions.Bluenose2A bstraction "
> objectClass=" org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditP art ">
> <action
> label="Create Abstract Block"
> class=" ca.uwaterloo.watform.bluenose2.diagram.ui.actions.CreateAbst ractBlockAction "
> menubarPath="additions"
> enablesFor="*"
> id="Bluenose2AbstractBlockAction">
> </action>
> </objectContribution>
> </extension>
>
> (2) action code:
>
> public class CreateAbstractBlockAction implements IObjectActionDelegate {
>
>
> private IWorkbenchPart myPart;
> private IStructuredSelection mySelection;
> private EObject parentBlock;
> private List childrenBlock;
> private IGraphicalEditPart someEditPart;
>
>
> public void setActivePart(IAction action, IWorkbenchPart targetPart) {
> myPart = targetPart;
> }
>
>
> public void selectionChanged(IAction action, ISelection selection) {
> mySelection = StructuredSelection.EMPTY;
>
> action.setEnabled(false);
> if (selection instanceof IStructuredSelection == false
> || selection.isEmpty()) {
> return;
> }
>
> if (myPart instanceof Bluenose2DiagramEditor == false)
> return;
>
> mySelection = (IStructuredSelection) selection;
> someEditPart = (IGraphicalEditPart) mySelection.getFirstElement();
>
> //postpone complicated checks till later when it's run
> action.setEnabled(true);
>
> }
>
>
> public void run(IAction action) {
>
> ProgressMonitorDialog progressDialog = new ProgressMonitorDialog(myPart.getSite().getShell());
>
> IRunnableWithProgress runnable = new IRunnableWithProgress() {
>
> public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
> /*
> * selected eobjects
> */
>
> monitor.beginTask("Creating abstract block", IProgressMonitor.UNKNOWN);
>
> monitor.subTask("Checking the selected elements");
>
>
> Set eobjects = new HashSet();
>
> Iterator selIt = mySelection.iterator();
> while (selIt.hasNext()) {
> IGraphicalEditPart editPart = (IGraphicalEditPart) selIt.next();
> EObject element = editPart.resolveSemanticElement();
> if (element instanceof Block)
> eobjects.add(element);
> }
>
>
> /*
> * children
> */
> childrenBlock = new LinkedList();
>
> Iterator eIt = eobjects.iterator();
> while (eIt.hasNext()) {
> EObject element = (EObject) eIt.next();
> if (eobjects.contains(element.eContainer()) == false)
> childrenBlock.add(element);
> }
>
> /*
> * all roots must be children block of the same block
> */
> boolean flag = true;
>
> parentBlock = null;
> Iterator childrenIt = childrenBlock.iterator();
> while (childrenIt.hasNext()) {
> EObject block = (EObject) childrenIt.next();
> //make sure it's a block
> if (block instanceof Block == false) {
> flag = false;
> break;
> }
> //check all blocks have the same parent
> if (parentBlock != null && block.eContainer() != parentBlock) {
> flag = false;
> break;
> }
>
> if (parentBlock == null)
> parentBlock = block.eContainer();
> }
>
> if (flag == false) {
> throw new InterruptedException();
> }
>
> monitor.subTask("Creating the abstract element");
>
>
> View parentView = (View) someEditPart.getModel();
> Diagram diagram = (Diagram) EMFCoreUtil.getContainer(parentView, NotationPackage.eINSTANCE.getDiagram());
> String diagramID = ViewUtil.getIdStr(diagram);
>
>
> AbstractTransactionalCommand createCommand = new CreateAbstractBlockCommand((Block) parentBlock, childrenBlock, diagramID);
> try {
> OperationHistoryFactory.getOperationHistory().execute(create Command, monitor, null);
> } catch (ExecutionException e){
> //ignore
> }
>
> }
>
> };
>
> try {
> progressDialog.run(true, true, runnable);
> } catch (Exception e) {
> //nada
> }
>
> (3) the command
>
> public class CreateAbstractBlockCommand extends AbstractTransactionalCommand {
>
> private List blocks;
>
> private Block parent;
>
> private String diagramID;
>
> private static String label = "Create Abstract Command";
>
> public CreateAbstractBlockCommand(Block parent, List blocks,
> String diagramID) {
> super(TransactionUtil.getEditingDomain(parent), label, Collections
> .singletonList(WorkspaceSynchronizer
> .getFile(parent.eResource())));
> this.blocks = blocks;
> this.parent = parent;
> this.diagramID = diagramID;
> }
>
> /**
> * @return The two port ends of the connection
> */
> protected CommandResult doExecuteWithResult(IProgressMonitor monitor,
> IAdaptable info) throws ExecutionException {
>
> AbstractBlock absBlock = B2CreationCommandUtil.createAbstractBlock(
> parent, monitor);
> absBlock.setDiagramID(diagramID);
> absBlock.getConcreteBlocks().addAll(blocks);
> createAbstractConnections(absBlock);
>
> return CommandResult.newOKCommandResult(absBlock);
>
> }
>
> /**
> * Configures the connections of the abstract block.
> */
> protected void createAbstractConnections(AbstractBlock absBlock) {
>
> /*
> * get recursively the concrete ends represented by this block
> */
> Set concEnds = new HashSet();
> Stack toProcess = new Stack();
>
> pushAll(toProcess, absBlock.getConcreteBlocks());
>
> while (toProcess.isEmpty() == false) {
> EObject element = (EObject) toProcess.pop();
> if (element instanceof End)
> concEnds.add(element);
> pushAll(toProcess, element.eContents());
> }
>
> /*
> * get connections going outside of the abstract block
> */
> List outgoingCons = new LinkedList();
> List incomingCons = new LinkedList();
> Iterator concEndsIt = concEnds.iterator();
> while (concEndsIt.hasNext()) {
> End concEnd = (End) concEndsIt.next();
> // outgoing
> {
> Iterator it = concEnd.getOutgoingConnections().iterator();
> while (it.hasNext()) {
> Connection con = (Connection) it.next();
> if (concEnds.contains(con.getDst()) == false)
> outgoingCons.add(con);
> }
> }
> // incoming
> {
> Iterator it = concEnd.getIncomingConnections().iterator();
> while (it.hasNext()) {
> Connection con = (Connection) it.next();
> if (concEnds.contains(con.getSrc()) == false)
> incomingCons.add(con);
> }
> }
> }
>
> /*
> * Create the abstract connections.
> */
> Map concDstEndToAbsCon = new HashMap();
> Map concDstEndToConcCon = new HashMap();
> // outgoing connections
> {
> Iterator it = outgoingCons.iterator();
> while (it.hasNext()) {
> Connection con = (Connection) it.next();
> End dstEnd = con.getDst();
> if (concDstEndToAbsCon.containsKey(dstEnd) == false) {
> AbstractConnection absCon = B2CreationCommandUtil
> .createAbstractConnection(absBlock, dstEnd,
> new NullProgressMonitor());
> concDstEndToAbsCon.put(dstEnd, absCon);
> concDstEndToConcCon.put(dstEnd, new LinkedList());
> }
> List concCons = (List) concDstEndToConcCon.get(dstEnd);
> concCons.add(con);
> }
> }
> //incoming connections
> Map concSrcEndToAbsCon = new HashMap();
> Map concSrcEndToConcCon = new HashMap();
> {
> Iterator it = incomingCons.iterator();
> while (it.hasNext()) {
> Connection con = (Connection) it.next();
> End srcEnd = con.getSrc();
> if (concSrcEndToAbsCon.containsKey(srcEnd) == false) {
> AbstractConnection absCon = B2CreationCommandUtil
> .createAbstractConnection(srcEnd, absBlock,
> new NullProgressMonitor());
> concSrcEndToAbsCon.put(srcEnd, absCon);
> concSrcEndToConcCon.put(srcEnd, new LinkedList());
> }
> List concCons = (List) concSrcEndToConcCon.get(srcEnd);
> concCons.add(con);
> }
> }
>
> //add the abstract connections to the abstract block
> //outgoing
> {
> Iterator it = concDstEndToAbsCon.keySet().iterator();
> while (it.hasNext()) {
> End dstEnd = (End) it.next();
> AbstractConnection absCon = (AbstractConnection) concDstEndToAbsCon
> .get(dstEnd);
> List concCons = (List) concDstEndToConcCon.get(dstEnd);
> absBlock.getOutgoingConnections().add(absCon);
> absCon.getConcreteConnections().addAll(concCons);
> }
> }
> //incoming
> {
> Iterator it = concSrcEndToAbsCon.keySet().iterator();
> while (it.hasNext()) {
> End srcEnd = (End) it.next();
> AbstractConnection absCon = (AbstractConnection) concSrcEndToAbsCon
> .get(srcEnd);
> List concCons = (List) concSrcEndToConcCon.get(srcEnd);
> absBlock.getIncomingConnections().add(absCon);
> absCon.getConcreteConnections().addAll(concCons);
> }
> }
>
> }
>
> /**
> * Push a list of elements onto a stack.
> *
> * @param stack
> * @param list
> */
> protected void pushAll(Stack stack, List list) {
> Iterator it = list.iterator();
> while (it.hasNext()) {
> stack.push(it.next());
> }
> }
>
> }
>
>
> On Wed, 01 Nov 2006 00:58:04 +0100, zazo7 wrote:
>
>> Hi there!
>>
>> I was wondering if there is any way to access diagram data from a custom
>> action (implementing IAction)? I have GMF-generated editor for my domain
>> model. I would like to add simple action to it (to the menu bar) which
>> can edit opened diagram.
>>
>> I've been looking for the solution almost all day. All I have is:
>>
>> ...
>> public class MyAction implements IAction {
>>
>> public void run() {
>>
>> IWorkbenchWindow workbenchWindow =
>> PlatformUI.getWorkbench().getActiveWorkbenchWindow();
>>
>> IWorkbenchPage activePage = workbenchWindow.getActivePage();
>> IEditorPart activeEditor = activePage.getActiveEditor();
>> IEditorInput editorInput = activeEditor.getEditorInput();
>> ...
>>
>>
>> Can anyone tell me if this is a right direction or a dead end?
>> I will appreciate any help.
>>
>> Regards
>>
>> Tommy
>

Thanks for the quick response Vlad. The example you provided was quite
verbose indeed, but I managed to get through it.

Thanks again.

T
SOLVED Re: Custom action in generated editor (very Similar Question) [message #73697 is a reply to message #73465] Fri, 03 November 2006 01:56 Go to previous message
Eclipse UserFriend
Thanks for your fast answer vlad,

that looks very nice and it works!

Greets Alex

Vlad Ciubotariu wrote:
> In your object contribution, as seen in the the previous post, specify the
> right type of the edit part corresponding to that node. So instead of
> IGraphicalEditPart put the qualified name of your edit part.
>
> vlad
Previous Topic:Re: How to override ItemProvider and use a custom table cell editor for a referenced Feature in the
Next Topic:edit Figures at runtime with external program
Goto Forum:
  


Current Time: Wed Sep 17 03:53:42 EDT 2025

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

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

Back to the top