Skip to main content



      Home
Home » Modeling » EMF » CutToClipboard Command problems
CutToClipboard Command problems [message #398317] Thu, 02 February 2006 06:41 Go to next message
Eclipse UserFriend
Hi,

I have three EClasses A, B, C.

B is contained by A, but referenced by C.

I generate Model, Edit and Editor classes.
The ItemProvider for C as generated shows B as a child, which is good.

Using the generated Tree Editor....
If I "cut" an instance of a B TreeNode when shown as a child of a C
TreeNode it is removed from the A TreeNode but not the C TreeNode. If I
save at this point the "cut" instance of B has no containing parent and
disappears from the saved file.
This behaviour differs from the Delete command which removes all
references of a removed B and it disappears completely. The DeleteCommand
does a Remove and then uses EcoreUtil to trawl and remove all references
to the instance.

What I really want to happen is for Cut to remove it from the context in
which I cut in in C not from A causing me all "unreferenced" problems.

Okay so override the Cut Command...( which means really overriding the
RemoveCommand ) but the problem is ... how to distinguish between when a B
is being shown to the user as a child of an A and as a child of a C.

Do I have the go all the way back to the Editors relationship with the SWT
TreeWidget to fix this up ( say at the selection listener level )?

Suppose I wanted to disable the Cut command for Bs but not to disable
delete - would I not face the same problem is overriding the
RemoveCommand?

At the momment I am working on the modification at the
Editor/TreeView/selectionlistener level. Can you suggest any better ( less
radical surgery ) method of doing this?
Re: CutToClipboard Command problems [message #398322 is a reply to message #398317] Thu, 02 February 2006 08:02 Go to previous messageGo to next message
Eclipse UserFriend
JF,

Perhaps we should support a CutAction that behaves more like the
DeleteAction and a CutCommand that behaves more like the DeleteCommand
(at least optionally). But I'm not sure that really solves your
problem. Normally for a given instance to be shown more than once in
the tree, at least one will be a warpper since a given object can have
at most one getParent. You could probably use that information (create
your own specialized wrappers) to specialize the behavior for only one
of those cases.


JF wrote:

> Hi,
>
> I have three EClasses A, B, C.
> B is contained by A, but referenced by C.
>
> I generate Model, Edit and Editor classes.
> The ItemProvider for C as generated shows B as a child, which is good.
>
> Using the generated Tree Editor....
> If I "cut" an instance of a B TreeNode when shown as a child of a C
> TreeNode it is removed from the A TreeNode but not the C TreeNode. If
> I save at this point the "cut" instance of B has no containing parent
> and disappears from the saved file. This behaviour differs from the
> Delete command which removes all references of a removed B and it
> disappears completely. The DeleteCommand does a Remove and then uses
> EcoreUtil to trawl and remove all references to the instance.
>
> What I really want to happen is for Cut to remove it from the context
> in which I cut in in C not from A causing me all "unreferenced" problems.
> Okay so override the Cut Command...( which means really overriding the
> RemoveCommand ) but the problem is ... how to distinguish between when
> a B is being shown to the user as a child of an A and as a child of a C.
>
> Do I have the go all the way back to the Editors relationship with the
> SWT TreeWidget to fix this up ( say at the selection listener level )?
>
> Suppose I wanted to disable the Cut command for Bs but not to disable
> delete - would I not face the same problem is overriding the
> RemoveCommand?
>
> At the momment I am working on the modification at the
> Editor/TreeView/selectionlistener level. Can you suggest any better (
> less radical surgery ) method of doing this?
>
>
Re: CutToClipboard Command problems [message #398324 is a reply to message #398322] Thu, 02 February 2006 08:25 Go to previous messageGo to next message
Eclipse UserFriend
Thanks Ed for clearing that up,

By Wrapper do you mean
1) a Wrapper object in the model
2) Some "Transient" content provider ( as used to insert non model
children in the Tree View )
3) ... something else .. is there some particular wrapper class to use?

Since I have other non containment references which are nicely edited "in
context" rather than purely "in containment context", I have quite a few
cases to change ...
Re: CutToClipboard Command problems [message #398326 is a reply to message #398324] Thu, 02 February 2006 09:35 Go to previous messageGo to next message
Eclipse UserFriend
This is a multi-part message in MIME format.
--------------000708040007020007090004
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

JF,

I meant door number 3. The method ItemProviderAdapter.createWrapper can
be used to create wrappers for children that aren't the result of a
containment reference:

else if (!((EReference)feature).isContainment())
{
value = new DelegatingWrapperItemProvider(value, object,
feature, index, adapterFactory);
}

This wrapper just delegates through to the underlying item provider for
that object, but it could be specialized. Maybe you can make all the
necessary changes in just one place...


JF wrote:

> Thanks Ed for clearing that up,
>
> By Wrapper do you mean 1) a Wrapper object in the model
> 2) Some "Transient" content provider ( as used to insert non model
> children in the Tree View )
> 3) ... something else .. is there some particular wrapper class to use?
>
> Since I have other non containment references which are nicely edited
> "in context" rather than purely "in containment context", I have quite
> a few cases to change ...
>
>


--------------000708040007020007090004
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
JF,<br>
<br>
I meant door number 3.
Re: CutToClipboard Command problems [message #398330 is a reply to message #398326] Thu, 02 February 2006 10:20 Go to previous messageGo to next message
Eclipse UserFriend
Thanks again,

So override isWrappingNeeded and createWrapper in the generated
ItemProvider for the "C" object which is not the container of the "B"
object and then create a subclass of DelegatingWrapperItemProvider which
filters commands and passes them on to the ItemProvider of "C" to
implement the bespoke behaviour for that case ( which in turn could be
generic ).
The wrapping is certainly useful for contextual operations...
Re: CutToClipboard Command problems - out of my tree [message #398442 is a reply to message #398322] Thu, 09 February 2006 06:51 Go to previous message
Eclipse UserFriend
I also had a problem with selection wrapping things outside of their
direct container.
This occurs because the getAffectedObjects of the
AffectedObjectsWrappingCommand inner class of
DelegatingWrapperItemProvider uses the results of the "real" command on
the non delegated ItemProvider to find out which of its children should be
selected ( i.e. the AffectedObjects ).
The "children" of the DelegatingWrapperItemProvider for this purpose are
simply the children of its delegateItemProvider stored in the childrenMap.
However the delegateItemProvider may also be adding wrappers to its
children, so the childrenMap will store wrappers not the "real" children.
In this case it is also necessary to add the "non-real" childs wrapped
object ( the real child ) to the childrenMap as well ( the only way I
could do this was by calling getValue() ).


Heres the code which worked for me....

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.DelegatingWrapperItemProvider;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.IWrapperItemProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;


public class EnhancedDelegatingWrapperItemProvider extends
DelegatingWrapperItemProvider
{


public EnhancedDelegatingWrapperItemProvider(Object value, Object owner,
EStructuralFeature feature, int index, AdapterFactory adapterFactory)
{
super(value, owner, feature, index, adapterFactory);
}


protected void updateChildren()
{
//If we are wrapping something in a context and that thing also wraps
its children
//then some of its children will be wrappers and therefore we need to
map to the thing that the child wraps
//as well as the child itself

HashSet newExtraMappings = new HashSet();

if (delegateItemProvider instanceof ITreeItemContentProvider)
{
boolean changed = false;
Set oldDelegateChildren = delegateChildren != null ? new
HashSet(delegateChildren) : Collections.EMPTY_SET;
delegateChildren =
((ITreeItemContentProvider)delegateItemProvider).getChildren (getDelegateValue());

if (childrenMap == null && !delegateChildren.isEmpty())
{
childrenMap = new HashMap();
}

// Wrap any new children and add them to the map. Remove each
current child from the set of old children.
//
for (Iterator i = delegateChildren.iterator(); i.hasNext(); )
{
Object child = i.next();

if (!childrenMap.containsKey(child))
{
IWrapperItemProvider wrapper = createWrapper(child, this,
adapterFactory);
childrenMap.put(child, wrapper);
if(child instanceof DelegatingWrapperItemProvider)
{
Object innervalue =
((DelegatingWrapperItemProvider)child).getValue();
if(innervalue != null)
{
newExtraMappings.add(innervalue);
childrenMap.put(innervalue, wrapper);
}
}
changed = true;
}
oldDelegateChildren.remove(child);
}

// Remove and dispose any wrappers for remaining old children.
//
if (!oldDelegateChildren.isEmpty())
{
changed = true;

for (Iterator i = oldDelegateChildren.iterator(); i.hasNext(); )
{
Object child = i.next();

IWrapperItemProvider wrapper =
(IWrapperItemProvider)childrenMap.remove(child);
if(child instanceof DelegatingWrapperItemProvider)
{
Object wrappedValue =
((DelegatingWrapperItemProvider)child).getValue();
if(wrappedValue != null &&
!newExtraMappings.contains(wrappedValue))
{
childrenMap.remove(wrappedValue);
}
}
if (wrapper != null)
{
wrapper.dispose();
}
}
}

// If any children were added or removed, reset the indices.
if (changed)
{
int index = 0;
for (Iterator i = delegateChildren.iterator(); i.hasNext();
index++)
{

((IWrapperItemProvider)childrenMap.get(i.next())).setIndex(i ndex);
}
}
}
else
{
delegateChildren = Collections.EMPTY_LIST;
}
}




}
Previous Topic:[Announce] EMF 2.2.0 I200602090000 is available
Next Topic:Bracketed type included with getText
Goto Forum:
  


Current Time: Sun Aug 03 17:56:06 EDT 2025

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

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

Back to the top