Home » Modeling » GMF (Graphical Modeling Framework) » Custom action in generated editor
Custom action in generated editor [message #72373] |
Tue, 31 October 2006 18:58  |
Eclipse User |
|
|
|
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   |
Eclipse User |
|
|
|
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 [message #73643 is a reply to message #72444] |
Thu, 02 November 2006 18:46   |
Eclipse User |
|
|
|
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  |
Eclipse User |
|
|
|
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
|
|
|
Goto Forum:
Current Time: Wed Sep 17 03:58:12 EDT 2025
Powered by FUDForum. Page generated in 0.27895 seconds
|