mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Added cell-editor support to DSF view model (bug# 159681).
This commit is contained in:
parent
91d2328263
commit
2b72c663b0
8 changed files with 178 additions and 21 deletions
|
@ -26,6 +26,8 @@ import org.eclipse.dd.dsf.ui.DsfUIPlugin;
|
|||
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IChildrenRequestMonitor;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditor;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor;
|
||||
|
@ -43,7 +45,8 @@ abstract public class AbstractVMAdapter
|
|||
implements IAsynchronousLabelAdapter,
|
||||
IAsynchronousContentAdapter,
|
||||
IModelProxyFactoryAdapter,
|
||||
IColumnPresentationFactoryAdapter
|
||||
IColumnPresentationFactoryAdapter,
|
||||
IColumnEditorFactoryAdapter
|
||||
{
|
||||
private final DsfSession fSession;
|
||||
|
||||
|
@ -193,4 +196,20 @@ abstract public class AbstractVMAdapter
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public IColumnEditor createColumnEditor(IPresentationContext context, Object element) {
|
||||
VMProvider provider = getViewModelProvider(context);
|
||||
if (provider != null) {
|
||||
return provider.createColumnEditor(element);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getColumnEditorId(IPresentationContext context, Object element) {
|
||||
VMProvider provider = getViewModelProvider(context);
|
||||
if (provider != null) {
|
||||
return provider.getColumnEditorId(element);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,11 @@ import org.eclipse.dd.dsf.concurrent.Done;
|
|||
import org.eclipse.dd.dsf.concurrent.DoneCollector;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.GetDataDone;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditor;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -123,6 +126,24 @@ abstract public class AbstractVMLayoutNode implements IVMLayoutNode {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of the IColumnEditorFactoryAdapter delegate. It
|
||||
* returns null, which means that no cell editor is configured.
|
||||
* @see IColumnEditorFactoryAdapter#createColumnEditor(IPresentationContext, Object)
|
||||
*/
|
||||
public IColumnEditor createColumnEditor(IVMContext vmc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of the IColumnEditorFactoryAdapter delegate. It
|
||||
* returns null, which means that no cell editor is configured.
|
||||
* @see IColumnEditorFactoryAdapter#getColumnEditorId(IPresentationContext, Object)
|
||||
*/
|
||||
public String getColumnEditorId(IVMContext vmc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that returns the child layout nodes which return
|
||||
* <code>true</code> to the <code>hasDeltaFlags()</code> test for the given
|
||||
|
|
|
@ -94,6 +94,7 @@ abstract public class DMContextVMLayoutNode<V extends IDMData> extends AbstractV
|
|||
/** Service tracker to be used by sub-classes */
|
||||
private DsfServicesTracker fServices;
|
||||
|
||||
private DsfSession fSession;
|
||||
|
||||
/**
|
||||
* Concrete class type that the elements of this schema node are based on.
|
||||
|
@ -112,10 +113,18 @@ abstract public class DMContextVMLayoutNode<V extends IDMData> extends AbstractV
|
|||
*/
|
||||
public DMContextVMLayoutNode(DsfSession session, Class<? extends IDMContext<V>> dmcClassType) {
|
||||
super(session.getExecutor());
|
||||
fSession = session;
|
||||
fServices = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId());
|
||||
fDMCClassType = dmcClassType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the session for use by sub-classes.
|
||||
*/
|
||||
protected DsfSession getSession() {
|
||||
return fSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the services tracker for sub-class use.
|
||||
*/
|
||||
|
|
|
@ -13,6 +13,9 @@ package org.eclipse.dd.dsf.ui.viewmodel;
|
|||
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.Done;
|
||||
import org.eclipse.dd.dsf.concurrent.GetDataDone;
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditor;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext;
|
||||
|
@ -89,6 +92,30 @@ public interface IVMLayoutNode {
|
|||
*/
|
||||
public void buildDelta(Object event, VMDelta parent, Done done);
|
||||
|
||||
/**
|
||||
* Creates a column editor for the given element. The interface that this
|
||||
* method is delegated to is synchronous, therefore it also needs to be thread
|
||||
* safe.
|
||||
*
|
||||
* @see IColumnEditorFactoryAdapter#createColumnEditor(IPresentationContext, Object)
|
||||
* @param vmc VM Context to return the editor for
|
||||
* @return
|
||||
*/
|
||||
@ThreadSafeAndProhibitedFromDsfExecutor("")
|
||||
public IColumnEditor createColumnEditor(IVMContext vmc);
|
||||
|
||||
/**
|
||||
* Returns the ID of the editor for the given element. The interface that this
|
||||
* method is delegated to is synchronous, therefore it also needs to be thread
|
||||
* safe.
|
||||
*
|
||||
* @see IColumnEditorFactoryAdapter#getColumnEditorId(IPresentationContext, Object)
|
||||
* @param vmc VM Context to return the editor ID for
|
||||
* @return
|
||||
*/
|
||||
@ThreadSafeAndProhibitedFromDsfExecutor("")
|
||||
public String getColumnEditorId(IVMContext vmc);
|
||||
|
||||
/**
|
||||
* Disposes the resources held by this node.
|
||||
*/
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.ui.viewmodel;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
@ -27,8 +29,10 @@ import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy;
|
|||
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IChildrenRequestMonitor;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditor;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor;
|
||||
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
|
||||
|
@ -69,7 +73,7 @@ public class VMProvider
|
|||
* null when first created, to allow sub-classes to prorperly configure the
|
||||
* root node in the sub-class constructor.
|
||||
*/
|
||||
private IVMRootLayoutNode fRootLayoutNode;
|
||||
private AtomicReference<IVMRootLayoutNode> fRootLayoutNodeRef = new AtomicReference<IVMRootLayoutNode>();
|
||||
|
||||
/**
|
||||
* Constructs the view model provider for given DSF session. The
|
||||
|
@ -80,7 +84,7 @@ public class VMProvider
|
|||
@ThreadSafe
|
||||
public VMProvider(DsfSession session, IVMRootLayoutNode rootLayoutNode) {
|
||||
fSession = session;
|
||||
fRootLayoutNode = rootLayoutNode;
|
||||
fRootLayoutNodeRef.set(rootLayoutNode);
|
||||
// Add ourselves as listener for DM events events.
|
||||
session.getExecutor().execute(new Runnable() {
|
||||
public void run() {
|
||||
|
@ -92,16 +96,25 @@ public class VMProvider
|
|||
});
|
||||
}
|
||||
|
||||
/** Sets the layout nodes */
|
||||
/**
|
||||
* Sets the layout nodes. This method is thread-safe, because it might
|
||||
* be called fromthe constructor, which itself is thread-safe.
|
||||
*/
|
||||
@ThreadSafe
|
||||
public void setRootLayoutNode(IVMRootLayoutNode rootLayoutNode) {
|
||||
if (fRootLayoutNode != null) {
|
||||
fRootLayoutNode.dispose();
|
||||
final IVMRootLayoutNode oldRootLayoutNode = fRootLayoutNodeRef.getAndSet(rootLayoutNode);
|
||||
if (oldRootLayoutNode != null) {
|
||||
// IVMLayoutNode has to be called on dispatch thread... for now at least.
|
||||
getSession().getExecutor().execute( new Runnable() {
|
||||
public void run() {
|
||||
oldRootLayoutNode.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
fRootLayoutNode = rootLayoutNode;
|
||||
}
|
||||
|
||||
public IVMRootLayoutNode getRootLayoutNode() {
|
||||
return fRootLayoutNode;
|
||||
return fRootLayoutNodeRef.get();
|
||||
}
|
||||
|
||||
/** Called to dispose the provider. */
|
||||
|
@ -109,8 +122,8 @@ public class VMProvider
|
|||
if (fRegisteredAsEventListener) {
|
||||
fSession.removeServiceEventListener(this);
|
||||
}
|
||||
if (fRootLayoutNode != null) {
|
||||
fRootLayoutNode.dispose();
|
||||
if (fRootLayoutNodeRef != null) {
|
||||
fRootLayoutNodeRef.get().dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,7 +269,7 @@ public class VMProvider
|
|||
* column info is fairly static, this method is thread-safe, and it will
|
||||
* not be called on the executor thread.
|
||||
*
|
||||
* @see IColumnEditorFactoryAdapter#createColumnEditor(IPresentationContext, Object)
|
||||
* @see IColumnPresentationFactoryAdapter#createColumnPresentation(IPresentationContext, Object)
|
||||
*/
|
||||
@ThreadSafe
|
||||
public IColumnPresentation createColumnPresentation(Object element) {
|
||||
|
@ -283,6 +296,24 @@ public class VMProvider
|
|||
return null;
|
||||
}
|
||||
|
||||
public IColumnEditor createColumnEditor(Object element) {
|
||||
IVMContext vmc = getVmcForObject(element);
|
||||
if (vmc == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return vmc.getLayoutNode().createColumnEditor(vmc);
|
||||
}
|
||||
|
||||
public String getColumnEditorId(Object element) {
|
||||
IVMContext vmc = getVmcForObject(element);
|
||||
if (vmc == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return vmc.getLayoutNode().getColumnEditorId(vmc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convenience method that finds the VMC corresponding to given parent
|
||||
|
@ -298,9 +329,14 @@ public class VMProvider
|
|||
* root VMC from the root node, and pass this root vmc to the root's
|
||||
* child layout nodes.
|
||||
*/
|
||||
if (parent.equals(fRootLayoutNode.getRootVMC().getInputObject())) {
|
||||
return fRootLayoutNode.getRootVMC();
|
||||
} else if (parent instanceof IVMContext){
|
||||
IVMRootLayoutNode rootLayoutNode = getRootLayoutNode();
|
||||
if (rootLayoutNode == null) {
|
||||
return null;
|
||||
}
|
||||
else if (parent.equals(rootLayoutNode.getRootVMC().getInputObject())) {
|
||||
return rootLayoutNode.getRootVMC();
|
||||
}
|
||||
else if (parent instanceof IVMContext){
|
||||
/*
|
||||
* The parent is a VMC. Check to make sure that the VMC
|
||||
* originated from a node in this ViewModelProvider. If it didn't
|
||||
|
@ -308,7 +344,7 @@ public class VMProvider
|
|||
* request is a stale request. So just ignore it.
|
||||
*/
|
||||
if (isOurLayoutNode( ((IVMContext)parent).getLayoutNode(),
|
||||
new IVMLayoutNode[] { fRootLayoutNode } ))
|
||||
new IVMLayoutNode[] { rootLayoutNode } ))
|
||||
{
|
||||
return (IVMContext)parent;
|
||||
}
|
||||
|
@ -339,8 +375,10 @@ public class VMProvider
|
|||
*/
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(final IDMEvent<?> event) {
|
||||
if (fRootLayoutNode.hasDeltaFlags(event)) {
|
||||
fRootLayoutNode.createDelta(event, new GetDataDone<IModelDelta>() {
|
||||
IVMRootLayoutNode rootLayoutNode = getRootLayoutNode();
|
||||
|
||||
if (rootLayoutNode != null && rootLayoutNode.hasDeltaFlags(event)) {
|
||||
rootLayoutNode.createDelta(event, new GetDataDone<IModelDelta>() {
|
||||
public void run() {
|
||||
if (getStatus().isOK()) {
|
||||
fModelProxy.fireModelChangedNonDispatch(getData());
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.concurrent;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation idicating that given package, class, method, can be accessed on
|
||||
* any thread, except on the dispatch thread of given DsfExecutor.
|
||||
* <br> This restriction is desirable if it is expected that the implementation
|
||||
* behavior is to block the calling thread and execute a transaction using an
|
||||
* executor. In this situation, if the call is made on the executor's dispach
|
||||
* thread, the execution would dead-lock.
|
||||
* <br>
|
||||
* If declared on package or type, a field or method could still be declared
|
||||
* with an annotation indicating that it's thread-safe.
|
||||
* <p>
|
||||
* Note: the runtime retention policy is there to allow automated testing
|
||||
* and validation code.
|
||||
*
|
||||
* @param value The value indicates the method to use to obtain the executor.
|
||||
* It should be null if it cannot be determined from the given object.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.PACKAGE, ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR})
|
||||
@Inherited
|
||||
@Documented
|
||||
public @interface ThreadSafeAndProhibitedFromDsfExecutor {
|
||||
String value();
|
||||
}
|
|
@ -22,7 +22,7 @@ import org.eclipse.dd.dsf.service.DsfSession;
|
|||
* @param <V> Data Model data type that this context is for.
|
||||
*/
|
||||
@Immutable
|
||||
public class AbstractDMContext<V extends IDMData> extends PlatformObject
|
||||
abstract public class AbstractDMContext<V extends IDMData> extends PlatformObject
|
||||
implements IDMContext<V>
|
||||
{
|
||||
private final String fSessionId;
|
||||
|
|
|
@ -17,7 +17,7 @@ import org.eclipse.dd.dsf.concurrent.Immutable;
|
|||
* required DM-Context reference.
|
||||
*/
|
||||
@Immutable
|
||||
public class AbstractDMEvent<V extends IDMContext<?>> implements IDMEvent<V> {
|
||||
abstract public class AbstractDMEvent<V extends IDMContext<?>> implements IDMEvent<V> {
|
||||
|
||||
private final V fModelContext;
|
||||
public AbstractDMEvent(V context) {
|
||||
|
|
Loading…
Add table
Reference in a new issue