| <html> |
| |
| <head> |
| <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> |
| <title>Providing copy & paste functionality</title> |
| <link href="../book.css" rel="Stylesheet" type="text/css"> |
| <link href="../code.css" rel="Stylesheet" type="text/css"> |
| </head> |
| |
| <body> |
| |
| <h1>Providing Copy & Paste Functionality</h1> |
| <h2>Copy & Paste Functionality</h2> |
| <p>The copy & paste of graphical elements is integrated with the general copy and |
| paste concept for models</p> |
| <p>Note, that copy & paste in graphical editors is always executed on the graphical |
| model-elements. This gives the freedom to implement copy & paste with different |
| semantics</p> |
| <ul> |
| <li>On paste a duplicate of the graphical pictogram element and of the underlying |
| business-model element is created. However, it is sometimes difficult to create |
| a duplicate of the business-model element, because the semantic boundaries of |
| it may be ambiguous, think of a “deep copy”.</li> |
| <li>On paste a duplicate of the graphical pictogram element is created, which |
| is associated to the same underlying business-model element as the originally |
| copied graphical pictogram element.</li> |
| </ul> |
| <p>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.</p> |
| <h2>Creating a Copy Feature</h2> |
| <p>First we have to create a copy feature and make it available in the feature provider.</p> |
| <p>A copy feature has to implement the interface |
| <a href="../../../javadoc/org/eclipse/graphiti/features/ICopyFeature.html">ICopyFeature</a>. |
| Instead of implementing it directly it should extend one of the available base classes. |
| In this example we extend the base class |
| <a href="../../../javadoc/org/eclipse/graphiti/ui/features/AbstractCopyFeature.html"> |
| AbstractCopyFeature</a>, which offers methods to easily access the clipboard. |
| </p> |
| <p>In this case we have to implement/overwrite two methods:</p> |
| <ul> |
| <li>The method |
| <a href="../../../javadoc/org/eclipse/graphiti/features/ICopyFeature.html#canCopy(org.eclipse.graphiti.features.context.ICopyContext)"> |
| canCopy</a> has to check if the given context (containing the selected elements) |
| can be copied to the clipboard.</li> |
| <li>The method |
| <a href="../../../javadoc/org/eclipse/graphiti/features/ICopyFeature.html#copy(org.eclipse.graphiti.features.context.ICopyContext)"> |
| copy</a> finally has to copy the given context to the clipboard. </li> |
| </ul> |
| <p>You can see the complete implementation of the copy feature here:</p> |
| <!-- Begin code ------------------------------------------------------------------------------- --> |
| <p> </p> |
| <div class="literallayout"> |
| <div class="incode"> |
| <p class="code"><span class="keyword">package </span>org.eclipse.graphiti.examples.tutorial.features;<br> <br> |
| <span class="keyword">public class</span> TutorialCopyEClassFeature |
| <span class="keyword">extends </span>AbstractCopyFeature {<br> <br> |
| <span class="keyword">public </span>TutorialCopyEClassFeature(IFeatureProvider |
| fp) {<br> |
| <span class="keyword">super</span>(fp);<br> }<br> <br> |
| <span class="keyword">public boolean</span> canCopy(ICopyContext context) |
| {<br> <span class="keyword">final |
| </span>PictogramElement[] pes = context.getPictogramElements();<br> |
| <span class="keyword">if</span> (pes == <span class="keyword">null |
| </span>|| pes.<span class="string"><em>length</em> </span>== 0) { |
| <span class="keyword">// nothing selected</span><br> |
| <span class="keyword">return false</span>;<br> |
| }<br> <br> |
| <span class="keyword">// return true, if all selected elements are a EClasses</span><br> |
| <span class="keyword">for </span>(PictogramElement pe : pes) {<br> |
| <span class="keyword">final </span>Object bo = getBusinessObjectForPictogramElement(pe);<br> |
| <span class="keyword">if</span> (!(bo <span class="keyword">instanceof |
| </span>EClass)) {<br> |
| <span class="keyword">return false</span>;<br> |
| }<br> }<br> |
| <span class="keyword">return true</span>;<br> }<br> <br> |
| <span class="keyword">public void</span> copy(ICopyContext context) {<br> |
| <span class="comment">// get the business-objects for all pictogram-elements<br> |
| // we already verified, that all business-objets are EClasses</span><br> |
| PictogramElement[] pes = context.getPictogramElements();<br> |
| Object[] bos = <span class="keyword">new </span>Object[pes.<span class="string"><em>length</em></span>];<br> |
| <span class="keyword">for </span>(<span class="keyword">int </span>i = 0; |
| i < pes.<span class="string"><em>length</em></span>; i++) {<br> |
| PictogramElement pe = pes[i];<br> |
| bos[i] = getBusinessObjectForPictogramElement(pe);<br> |
| }<br> <span class="comment">// |
| put all business objects to the clipboard</span><br> |
| putToClipboard(bos);<br> }<br>}<br></p> |
| </div> |
| </div> |
| <p> </p> |
| <!-- End code ------------------------------------------------------------------------------- --> |
| <p>Additionally the feature provider has to deliver our newly created feature (overwrite |
| the method |
| <a href="../../../javadoc/org/eclipse/graphiti/features/IFeatureProvider.html#getCopyFeature(org.eclipse.graphiti.features.context.ICopyContext)"> |
| getCopyFeature</a>). </p> |
| <p>This implementation can be seen here: </p> |
| <!-- Begin code ------------------------------------------------------------------------------- --> |
| <p> </p> |
| <div class="literallayout"> |
| <div class="incode"> |
| <p class="code">@Override<br>public ICopyFeature getCopyFeature(ICopyContext |
| context) {<br> <span class="keyword">return new</span> |
| TutorialCopyEClassFeature(<span class="keyword">this</span>);<br>} </p> |
| </div> |
| </div> |
| <p> </p> |
| <!-- End code ------------------------------------------------------------------------------- --> |
| <h2>Creating a Paste Feature</h2> |
| <p>Now we have to create a corresponding paste feature and make it available in |
| the feature provider.</p> |
| <p>A paste feature has to implement the interface |
| <a href="../../../javadoc/org/eclipse/graphiti/features/IPasteFeature.html">IPasteFeature</a>. |
| Instead of implementing it directly it should extend one of the available base classes. |
| In this example we extend the base class |
| <a href="../../../javadoc/org/eclipse/graphiti/ui/features/AbstractPasteFeature.html"> |
| AbstractPasteFeature</a>, which offers methods to easily access the clipboard. |
| </p> |
| <p>In this case we have to implement/overwrite two methods:</p> |
| <ul> |
| <li>The method |
| <a href="../../../javadoc/org/eclipse/graphiti/features/IPasteFeature.html#canPaste(org.eclipse.graphiti.features.context.IPasteContext)"> |
| canPaste</a> has to check if the current clipboard contents can be pasted on |
| the given context (containing the target object).</li> |
| <li>The method |
| <a href="../../../javadoc/org/eclipse/graphiti/features/IPasteFeature.html#paste(org.eclipse.graphiti.features.context.IPasteContext)"> |
| paste</a> finally has to paste the current clipboard contents on the given context. |
| </li> |
| </ul> |
| <p>You can see the complete implementation of the paste feature here:</p> |
| <!-- Begin code ------------------------------------------------------------------------------- --> |
| <p> </p> |
| <div class="literallayout"> |
| <div class="incode"> |
| <p class="code"><span class="keyword">package </span>org.eclipse.graphiti.examples.tutorial.features;<br> <br> |
| <span class="keyword">public class</span> TutorialPasteEClassFeature |
| <span class="keyword">extends </span>AbstractPasteFeature {<br> <br> |
| <span class="keyword">public </span>TutorialPasteEClassFeature(IFeatureProvider |
| fp) {<br> |
| <span class="keyword">super</span>(fp);<br> }<br> <br> |
| <span class="keyword">public boolean</span> canPaste(IPasteContext context) |
| {<br> <span class="comment">// |
| only support pasting directly in the diagram (nothing else selected)</span><br> |
| PictogramElement[] pes = context.getPictogramElements();<br> |
| if (pes.<span class="string"><em>length</em> </span>!= 1 || !(pes[0] |
| <span class="keyword">instanceof </span>Diagram)) {<br> |
| <span class="keyword">return false</span>;<br> |
| }<br> <br> |
| <span class="comment">// can paste, if all objects on the clipboard are |
| EClasses</span><br> Object[] fromClipboard |
| = getFromClipboard();<br> if (fromClipboard |
| == null || fromClipboard.<span class="string"><em>length</em> </span>== |
| 0) {<br> |
| <span class="keyword">return false</span>;<br> |
| }<br> <span class="keyword">for |
| </span>(Object object : fromClipboard) {<br> |
| <span class="keyword">if</span> (!(object <span class="keyword">instanceof |
| </span>EClass)) {<br> |
| <span class="keyword">return false</span>;<br> |
| }<br> }<br> |
| <span class="keyword">return true</span>;<br> }<br> <br> |
| <span class="keyword"> public void </span>paste(IPasteContext context) |
| {<br> <span class="comment">// |
| we already verified, that we paste directly in the diagram</span><br> |
| PictogramElement[] pes = context.getPictogramElements();<br> |
| Diagram diagram = (Diagram) pes[0];<br> |
| <span class="comment">// get the EClasses from the clipboard without copying |
| them<br> // (only copy the pictogram |
| element, not the business object)<br> |
| // then create new pictogram elements using the add feature</span><br> |
| Object[] objects = getFromClipboard();<br> |
| <span class="keyword">for </span>(Object object : objects) {<br> |
| AddContext ac = <span class="keyword">new </span>AddContext();<br> |
| ac.setLocation(0, 0); <span class="comment">// for simplicity paste at (0, |
| 0)</span><br> |
| ac.setTargetContainer(diagram);<br> |
| addGraphicalRepresentation(ac, object);<br> |
| }<br> }<br>}<br></p> |
| </div> |
| </div> |
| <p> </p> |
| <!-- End code ------------------------------------------------------------------------------- --> |
| <p>Additionally the feature provider has to deliver our newly created feature (overwrite |
| the method |
| <a href="../../../javadoc/org/eclipse/graphiti/features/IFeatureProvider.html#getPasteFeature(org.eclipse.graphiti.features.context.IPasteContext)"> |
| getPasteFeature</a>). </p> |
| <p>This implementation can be seen here: </p> |
| <!-- Begin code ------------------------------------------------------------------------------- --> |
| <p> </p> |
| <div class="literallayout"> |
| <div class="incode"> |
| <p class="code">@Override<br><span class="keyword">public </span>IPasteFeature |
| getPasteFeature(IPasteContext context) {<br> |
| <span class="keyword">return new</span> TutorialPasteEClassFeature(this);<br> |
| } </p> |
| </div> |
| </div> |
| <p> </p> |
| <!-- End code ------------------------------------------------------------------------------- --> |
| <h2>Test: Copy & Paste a EClass</h2> |
| <p>Now start the editor again </p> |
| <ul> |
| <li>Create a new EClass.</li> |
| <li>Copy the EClass to the clipboard using the context-menu.</li> |
| <li>Paste the clipboard to the diagram using the context-menu, so that a new |
| EClass is created in the upper-left corner of the diagram (in future versions |
| of the graphics framework it will be possible to paste at the current mouse-location).</li> |
| <li>Verify that in the context-menu of a EClass the paste action is disabled.</li> |
| <li>Rename the new EClass, and verify that the other EClass is also renamed. |
| This happens, because the implementation only duplicates the graphical pictogram |
| element and not the underlying business-model element. <br>Note: it might be |
| necessary to explicitly call the update-action on the other EClass. This is |
| currently in discussion in Graphitti. </li> |
| </ul> |
| |
| </body> |
| |
| </html> |