The copy & paste of graphical elements is integrated with the general copy and paste concept for models
Note, that copy & paste in diagrams is always executed on the graphical model-elements. This gives the freedom to implement copy & paste with different semantics
Below we will explain an example, which provides copy & paste functionality for EClasses. For simplicity reasons we only create a duplicate of the graphical pictogram element and not also of the business-model element.
First we have to create a copy feature and make it available in the feature provider.
A copy feature has to implement the interface ICopyFeature. Instead of implementing it directly it should extend one of the available base classes. In this example we extend the base class AbstractCopyFeature, which offers methods to easily access the clipboard.
In this case we have to implement/overwrite two methods:
You can see the complete implementation of the copy feature here:
package org.eclipse.graphiti.examples.tutorial.features;
public class TutorialCopyEClassFeature
extends AbstractCopyFeature {
public TutorialCopyEClassFeature(IFeatureProvider
fp) {
super(fp);
}
public boolean canCopy(ICopyContext
context) {
final PictogramElement[] pes =
context.getPictogramElements();
if (pes == null
|| pes.length == 0) { // nothing selected
return false;
}
// return true, if all selected
elements are a EClasses
for (PictogramElement pe : pes) {
final Object bo =
getBusinessObjectForPictogramElement(pe);
if (!(bo instanceof
EClass)) {
return false;
}
}
return true;
}
public
void copy(ICopyContext context) {
// get the business-objects for all
pictogram-elements
// we already verified, that all business-objets are EClasses
PictogramElement[] pes = context.getPictogramElements();
Object[] bos = new Object[pes.length ];
for (int i
= 0; i < pes.length ; i++) {
PictogramElement pe = pes[i];
bos[i] = getBusinessObjectForPictogramElement(pe);
}
// put all business objects to the clipboard
putToClipboard(bos);
}
}
Additionally the feature provider has to deliver our newly created feature (overwrite the method getCopyFeature).
This implementation can be seen here:
@Override
public ICopyFeature
getCopyFeature(ICopyContext context) {
return new TutorialCopyEClassFeature(this);
}
Now we have to create a corresponding paste feature and make it available in the feature provider.
A paste feature has to implement the interface IPasteFeature. Instead of implementing it directly it should extend one of the available base classes. In this example we extend the base class AbstractPasteFeature, which offers methods to easily access the clipboard.
In this case we have to implement/overwrite two methods:
You can see the complete implementation of the paste feature here:
package org.eclipse.graphiti.examples.tutorial.features;
public class TutorialPasteEClassFeature
extends AbstractPasteFeature {
public TutorialPasteEClassFeature(IFeatureProvider
fp) {
super(fp);
}
public boolean canPaste(IPasteContext
context) {
// only support pasting directly in the
diagram (nothing else selected)
PictogramElement[] pes = context.getPictogramElements();
if (pes.length != 1 || !(pes[0]
instanceof Diagram)) {
return false;
}
// can paste, if all objects on the
clipboard are EClasses
Object[] fromClipboard = getFromClipboard();
if (fromClipboard == null || fromClipboard.length
== 0) {
return false;
}
for (Object object : fromClipboard) {
if (!(object instanceof
EClass)) {
return false;
}
}
return true;
}
public
void paste(IPasteContext context) {
// we already verified, that we paste
directly in the diagram
PictogramElement[] pes = context.getPictogramElements();
Diagram diagram = (Diagram) pes[0];
// get the EClasses from the clipboard
without copying them
// (only copy the pictogram element, not the business object)
// then create new pictogram elements using the add feature
Object[] objects = getFromClipboard();
for (Object object : objects) {
AddContext ac = new AddContext();
// For simplicity paste all objects at
the location given in the
// context (no stacking or similar)
ac.setLocation(context.getX(), context.getY());
ac.setTargetContainer(diagram);
addGraphicalRepresentation(ac, object);
}
}
}
Additionally the feature provider has to deliver our newly created feature (overwrite the method getPasteFeature).
This implementation can be seen here:
@Override
public IPasteFeature
getPasteFeature(IPasteContext context) {
return new
TutorialPasteEClassFeature(this);
}
Now start the editor again
Note: The example coding in this tutorial restricts the copy and paste process to the graphical representation. The domain or business objects behind the representation (the EClass objects) will not be copied along. In a real tool implementation this can of course also be modified to also copy the domain objects along with the representation.
Note on performance: The methods canCopy and canPaste are called often, so try to keep them as lightweight as possible to avoid performance issues.
Note: Tools might need to check if a pasted object can be resolved in the scope of the target diagram editor or viewer; objects might e.g. not be reolvable in case they were just created inside another editor and were not yet saved to any resource. In case a pasted object cannot be resolved some special handling might be necessary. This could e.g. be that it is not allowed to paste such objects or that the domain object needs to be created together with its representation in the target diagram; in any case this needs to be handled by the domain editor in a suitable way. The graphiti framework offers the method isResolvable to determine this. An example is shown in the implemented version of the tutorial; it shows how to disable paste in such a case.