CutToClipboard Command problems [message #398317] |
Thu, 02 February 2006 06:41  |
Eclipse User |
|
|
|
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 #398326 is a reply to message #398324] |
Thu, 02 February 2006 09:35   |
Eclipse User |
|
|
|
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 - out of my tree [message #398442 is a reply to message #398322] |
Thu, 09 February 2006 06:51  |
Eclipse User |
|
|
|
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;
}
}
}
|
|
|
Powered by
FUDForum. Page generated in 0.18265 seconds