diff options
author | Darin Wright | 2006-11-10 17:42:45 +0000 |
---|---|---|
committer | Darin Wright | 2006-11-10 17:42:45 +0000 |
commit | 450acea253fd30b36676d4eafeef94fe8bd0ff02 (patch) | |
tree | 5e66ae7d409a74b6058ab8917d383a5dfeaa1a65 /org.eclipse.debug.ui | |
parent | 3736733ce60a840ed3df5d127df8abead41dcfcb (diff) | |
download | eclipse.platform.debug-450acea253fd30b36676d4eafeef94fe8bd0ff02.tar.gz eclipse.platform.debug-450acea253fd30b36676d4eafeef94fe8bd0ff02.tar.xz eclipse.platform.debug-450acea253fd30b36676d4eafeef94fe8bd0ff02.zip |
Bug 153500 Asynchronous model viewer
Diffstat (limited to 'org.eclipse.debug.ui')
126 files changed, 7327 insertions, 643 deletions
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/AsynchronousDebugLabelAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/AsynchronousDebugLabelAdapter.java index 04d3f991c..7f84fba56 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/AsynchronousDebugLabelAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/AsynchronousDebugLabelAdapter.java @@ -20,9 +20,10 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.internal.ui.DelegatingModelPresentation; import org.eclipse.debug.internal.ui.LazyModelPresentation; +import org.eclipse.debug.internal.ui.viewers.PartPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousLabelAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.views.launch.DebugElementHelper; import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.debug.ui.IDebugView; @@ -46,29 +47,32 @@ public class AsynchronousDebugLabelAdapter extends AsynchronousLabelAdapter { // Honor view specific settings in a debug view by copying model presentation settings // into the debug element helper's presentation before we get the label. This allows // for qualified name and type name settings to remain in tact. - if (element instanceof IDebugElement && context.getPart() instanceof IDebugView) { - IWorkbenchPart part = context.getPart(); - if (part instanceof IDebugView) { - IDebugModelPresentation pres = ((IDebugView)part).getPresentation(((IDebugElement)element).getModelIdentifier()); - Map settings = null; - synchronized (presentation) { - if (pres instanceof DelegatingModelPresentation) { - settings = ((DelegatingModelPresentation)pres).getAttributes(); - } else if (pres instanceof LazyModelPresentation) { - settings = ((LazyModelPresentation)pres).getAttributes(); - } - if (settings != null) { - Iterator iterator = settings.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Entry) iterator.next(); - presentation.setAttribute((String) entry.getKey(), entry.getValue()); - } - super.computeLabels(element, context, monitor); - return; - } - } - } - } + if (context instanceof PartPresentationContext) { + PartPresentationContext ppc = (PartPresentationContext) context; + if (element instanceof IDebugElement && ppc.getPart() instanceof IDebugView) { + IWorkbenchPart part = ppc.getPart(); + if (part instanceof IDebugView) { + IDebugModelPresentation pres = ((IDebugView)part).getPresentation(((IDebugElement)element).getModelIdentifier()); + Map settings = null; + synchronized (presentation) { + if (pres instanceof DelegatingModelPresentation) { + settings = ((DelegatingModelPresentation)pres).getAttributes(); + } else if (pres instanceof LazyModelPresentation) { + settings = ((LazyModelPresentation)pres).getAttributes(); + } + if (settings != null) { + Iterator iterator = settings.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Entry) iterator.next(); + presentation.setAttribute((String) entry.getKey(), entry.getValue()); + } + super.computeLabels(element, context, monitor); + return; + } + } + } + } + } super.computeLabels(element, context, monitor); } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/DebugTargetContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/DebugTargetContentAdapter.java index a7c1a363a..b950f44f4 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/DebugTargetContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/DebugTargetContentAdapter.java @@ -15,8 +15,8 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IMemoryBlockRetrieval; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; public class DebugTargetContentAdapter extends AsynchronousContentAdapter { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/DefaultVariableCellModifier.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/DefaultVariableCellModifier.java index 45b3ac35e..ff566ca5c 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/DefaultVariableCellModifier.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/DefaultVariableCellModifier.java @@ -15,11 +15,8 @@ import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.DefaultLabelProvider; import org.eclipse.debug.internal.ui.VariableValueEditorManager; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.ui.actions.IVariableValueEditor; import org.eclipse.jface.viewers.ICellModifier; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchPart; /** * @since 3.2 @@ -27,12 +24,6 @@ import org.eclipse.ui.IWorkbenchPart; */ public class DefaultVariableCellModifier implements ICellModifier { - private IPresentationContext fContext; - - public DefaultVariableCellModifier(IPresentationContext context) { - fContext = context; - } - /* (non-Javadoc) * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object, java.lang.String) */ @@ -72,36 +63,22 @@ public class DefaultVariableCellModifier implements ICellModifier { if (element instanceof IVariable) { IVariable variable = (IVariable) element; IVariableValueEditor editor = VariableValueEditorManager.getDefault().getVariableValueEditor(variable.getModelIdentifier()); - Shell shell = null; - IWorkbenchPart part = fContext.getPart(); - if (part != null) { - shell = part.getSite().getShell(); - } if (value instanceof String) { value = DefaultLabelProvider.encodeEsacpedChars((String)value); } if (editor != null) { - if (editor.saveVariable(variable, (String) value, shell)) { + if (editor.saveVariable(variable, (String) value, DebugUIPlugin.getShell())) { return; } } try { variable.setValue((String) value); } catch (DebugException e) { - DebugUIPlugin.errorDialog(shell, Messages.VariableColumnPresentation_4, Messages.VariableColumnPresentation_5, e.getStatus()); + DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), Messages.VariableColumnPresentation_4, Messages.VariableColumnPresentation_5, e.getStatus()); } } } } } - - /** - * Returns the context in which this cell modifier is being used. - * - * @return presentation context - */ - protected IPresentationContext getPresentationContext() { - return fContext; - } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ExpressionContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ExpressionContentAdapter.java index 35f210113..150715500 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ExpressionContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ExpressionContentAdapter.java @@ -14,7 +14,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.model.IErrorReportingExpression; import org.eclipse.debug.core.model.IExpression; import org.eclipse.debug.core.model.IValue; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; /** * diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ExpressionLabelAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ExpressionLabelAdapter.java index f5864138f..3152de76e 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ExpressionLabelAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ExpressionLabelAdapter.java @@ -13,7 +13,7 @@ package org.eclipse.debug.internal.ui.elements.adapters; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.model.IErrorReportingExpression; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.swt.graphics.RGB; public class ExpressionLabelAdapter extends VariableLabelAdapter { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ExpressionManagerContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ExpressionManagerContentAdapter.java index f52b40ac2..934e193b2 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ExpressionManagerContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ExpressionManagerContentAdapter.java @@ -13,8 +13,8 @@ package org.eclipse.debug.internal.ui.elements.adapters; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.IExpressionManager; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; public class ExpressionManagerContentAdapter extends AsynchronousContentAdapter { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/LauchManagerContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/LauchManagerContentAdapter.java index a42e406d6..ce2448936 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/LauchManagerContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/LauchManagerContentAdapter.java @@ -13,8 +13,8 @@ package org.eclipse.debug.internal.ui.elements.adapters; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; public class LauchManagerContentAdapter extends AsynchronousContentAdapter { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/LaunchContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/LaunchContentAdapter.java index 67eda6a76..f9d5e65eb 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/LaunchContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/LaunchContentAdapter.java @@ -13,8 +13,8 @@ package org.eclipse.debug.internal.ui.elements.adapters; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; public class LaunchContentAdapter extends AsynchronousContentAdapter { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemoryBlockContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemoryBlockContentAdapter.java index 890ee29e2..71cf1a685 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemoryBlockContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemoryBlockContentAdapter.java @@ -26,8 +26,8 @@ import org.eclipse.debug.internal.ui.DebugUIMessages; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.memory.provisional.AbstractAsyncTableRendering; import org.eclipse.debug.internal.ui.memory.provisional.MemoryViewPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil; import org.eclipse.debug.internal.ui.views.memory.renderings.MemorySegment; import org.eclipse.debug.internal.ui.views.memory.renderings.TableRenderingContentDescriptor; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemoryBlockLabelAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemoryBlockLabelAdapter.java index 3da0ce5c1..6e9c3c116 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemoryBlockLabelAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemoryBlockLabelAdapter.java @@ -15,7 +15,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IMemoryBlockExtension; import org.eclipse.debug.internal.ui.DebugPluginImages; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.resource.ImageDescriptor; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemoryRetrievalContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemoryRetrievalContentAdapter.java index 69ed3da84..eb963920b 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemoryRetrievalContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemoryRetrievalContentAdapter.java @@ -14,8 +14,8 @@ package org.eclipse.debug.internal.ui.elements.adapters; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IMemoryBlockRetrieval; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; public class MemoryRetrievalContentAdapter extends AsynchronousContentAdapter{ diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemorySegmentLabelAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemorySegmentLabelAdapter.java index 5f93411eb..54203616c 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemorySegmentLabelAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/MemorySegmentLabelAdapter.java @@ -20,8 +20,8 @@ import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.memory.provisional.AbstractAsyncTableRendering; import org.eclipse.debug.internal.ui.memory.provisional.MemoryViewPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousLabelAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.views.launch.DebugElementHelper; import org.eclipse.debug.internal.ui.views.memory.renderings.AbstractBaseTableRendering; import org.eclipse.debug.internal.ui.views.memory.renderings.MemorySegment; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ProcessContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ProcessContentAdapter.java index 7cfbec4b8..0fad21614 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ProcessContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ProcessContentAdapter.java @@ -11,8 +11,8 @@ package org.eclipse.debug.internal.ui.elements.adapters; import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; public class ProcessContentAdapter extends AsynchronousContentAdapter { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/RegisterGroupContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/RegisterGroupContentAdapter.java index fff4f0942..da3947263 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/RegisterGroupContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/RegisterGroupContentAdapter.java @@ -12,8 +12,8 @@ package org.eclipse.debug.internal.ui.elements.adapters; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.model.IRegisterGroup; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; public class RegisterGroupContentAdapter extends AsynchronousContentAdapter { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/StackFrameContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/StackFrameContentAdapter.java index c281b6eff..cc7dfe652 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/StackFrameContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/StackFrameContentAdapter.java @@ -13,8 +13,8 @@ package org.eclipse.debug.internal.ui.elements.adapters; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; public class StackFrameContentAdapter extends AsynchronousContentAdapter { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ThreadContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ThreadContentAdapter.java index 5539c24a6..78c52fd5e 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ThreadContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/ThreadContentAdapter.java @@ -13,8 +13,8 @@ package org.eclipse.debug.internal.ui.elements.adapters; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.model.IThread; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; public class ThreadContentAdapter extends AsynchronousContentAdapter { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableColumnEditor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableColumnEditor.java index 27aaac419..9c42bb683 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableColumnEditor.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableColumnEditor.java @@ -43,7 +43,7 @@ public class VariableColumnEditor extends AbstractColumnEditor { */ public ICellModifier getCellModifier() { if (fCellModifier == null) { - fCellModifier = new DefaultVariableCellModifier(getPresentationContext()); + fCellModifier = new DefaultVariableCellModifier(); } return fCellModifier; } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableColumnFactoryAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableColumnFactoryAdapter.java index 7ddb85d94..d6d5ef606 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableColumnFactoryAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableColumnFactoryAdapter.java @@ -12,11 +12,11 @@ package org.eclipse.debug.internal.ui.elements.adapters; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IVariable; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; 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.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; /** diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableContentAdapter.java index e66053e24..8da34035c 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableContentAdapter.java @@ -22,12 +22,11 @@ import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IIndexedValue; import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.core.model.IVariable; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.views.variables.IndexedVariablePartition; import org.eclipse.debug.internal.ui.views.variables.VariablesView; import org.eclipse.debug.ui.IDebugUIConstants; -import org.eclipse.ui.IWorkbenchPart; public class VariableContentAdapter extends AsynchronousContentAdapter { @@ -175,11 +174,8 @@ public class VariableContentAdapter extends AsynchronousContentAdapter { * in the specified context */ protected boolean isShowLogicalStructure(IPresentationContext context) { - IWorkbenchPart part = context.getPart(); - if (part instanceof VariablesView) { - return ((VariablesView) part).isShowLogicalStructure(); - } - return false; + Boolean show = (Boolean) context.getProperty(VariablesView.PRESENTATION_SHOW_LOGICAL_STRUCTURES); + return show != null && show.booleanValue(); } /** diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableLabelAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableLabelAdapter.java index e730c6cc8..91176baed 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableLabelAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/elements/adapters/VariableLabelAdapter.java @@ -19,7 +19,7 @@ import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.DefaultLabelProvider; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.swt.graphics.RGB; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/memory/provisional/AbstractAsyncTableRendering.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/memory/provisional/AbstractAsyncTableRendering.java index f6318af9a..dc5d3b295 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/memory/provisional/AbstractAsyncTableRendering.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/memory/provisional/AbstractAsyncTableRendering.java @@ -34,8 +34,9 @@ import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.memory.IPersistableDebugElement; import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil; import org.eclipse.debug.internal.ui.views.memory.renderings.AbstractBaseTableRendering; import org.eclipse.debug.internal.ui.views.memory.renderings.AbstractVirtualContentTableModel; @@ -419,7 +420,7 @@ public abstract class AbstractAsyncTableRendering extends AbstractBaseTableRende }; private IModelChangedListener fModelChangedListener = new IModelChangedListener() { - public void modelChanged(IModelDelta delta) { + public void modelChanged(IModelDelta delta, IModelProxy proxy) { if (delta.getElement() == getMemoryBlock()) { showTable(); diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/memory/provisional/MemoryViewPresentationContext.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/memory/provisional/MemoryViewPresentationContext.java index 1e367983b..ade979113 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/memory/provisional/MemoryViewPresentationContext.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/memory/provisional/MemoryViewPresentationContext.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.debug.internal.ui.memory.provisional; -import org.eclipse.debug.internal.ui.viewers.PresentationContext; +import org.eclipse.debug.internal.ui.viewers.PartPresentationContext; import org.eclipse.debug.ui.memory.IMemoryRendering; import org.eclipse.debug.ui.memory.IMemoryRenderingContainer; import org.eclipse.debug.ui.memory.IMemoryRenderingSite; @@ -24,7 +24,7 @@ import org.eclipse.debug.ui.memory.IMemoryRenderingSite; * @since 3.2 * */ -public class MemoryViewPresentationContext extends PresentationContext { +public class MemoryViewPresentationContext extends PartPresentationContext { private IMemoryRenderingContainer fContainer; private IMemoryRendering fRendering; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/DebugElementLabelProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/DebugElementLabelProvider.java new file mode 100644 index 000000000..7b23c987e --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/DebugElementLabelProvider.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.views.DebugModelPresentationContext; +import org.eclipse.debug.internal.ui.views.launch.DebugElementHelper; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; + +/** + * @since 3.3 + */ +public class DebugElementLabelProvider extends ElementLabelProvider { + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getLabel(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, java.lang.String) + */ + protected String getLabel(Object element, IPresentationContext presentationContext, String columnId) throws CoreException { + if (presentationContext instanceof DebugModelPresentationContext) { + DebugModelPresentationContext debugContext = (DebugModelPresentationContext) presentationContext; + return debugContext.getModelPresentation().getText(element); + } + return DebugElementHelper.getLabel(element); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getBackground(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, java.lang.String) + */ + protected RGB getBackground(Object element, IPresentationContext presentationContext, String columnId) throws CoreException { + if (presentationContext instanceof DebugModelPresentationContext) { + DebugModelPresentationContext debugContext = (DebugModelPresentationContext) presentationContext; + return DebugElementHelper.getBackground(element, debugContext.getModelPresentation()); + } + return DebugElementHelper.getBackground(element); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getFontDatas(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, java.lang.String) + */ + protected FontData getFontData(Object element, IPresentationContext presentationContext, String columnId) throws CoreException { + if (presentationContext instanceof DebugModelPresentationContext) { + DebugModelPresentationContext debugContext = (DebugModelPresentationContext) presentationContext; + return DebugElementHelper.getFont(element, debugContext.getModelPresentation()); + + } + return DebugElementHelper.getFont(element); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getForeground(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, java.lang.String) + */ + protected RGB getForeground(Object element, IPresentationContext presentationContext, String columnId) throws CoreException { + if (presentationContext instanceof DebugModelPresentationContext) { + DebugModelPresentationContext debugContext = (DebugModelPresentationContext) presentationContext; + return DebugElementHelper.getForeground(element, debugContext.getModelPresentation()); + } + return DebugElementHelper.getForeground(element); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getImageDescriptor(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, java.lang.String) + */ + protected ImageDescriptor getImageDescriptor(Object element, IPresentationContext presentationContext, String columnId) throws CoreException { + if (presentationContext instanceof DebugModelPresentationContext) { + DebugModelPresentationContext debugContext = (DebugModelPresentationContext) presentationContext; + return DebugElementHelper.getImageDescriptor(element, debugContext.getModelPresentation()); + } + return DebugElementHelper.getImageDescriptor(element); + } + + + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/DebugTargetContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/DebugTargetContentProvider.java new file mode 100644 index 000000000..b077874e7 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/DebugTargetContentProvider.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.IDebugUIConstants; + +/** + * @since 3.3 + */ +public class DebugTargetContentProvider extends ElementContentProvider { + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected int getChildCount(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return ((IDebugTarget)element).getThreads().length; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#supportsContextId(java.lang.String) + */ + protected boolean supportsContextId(String id) { + return IDebugUIConstants.ID_DEBUG_VIEW.equals(id); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return getElements(((IDebugTarget)parent).getThreads(), index, length); + } + + protected boolean hasChildren(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return ((IDebugTarget)element).hasThreads(); + } + + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ElementContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ElementContentProvider.java new file mode 100644 index 000000000..3ebaedbba --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ElementContentProvider.java @@ -0,0 +1,261 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.viewers.TreePath; + +/** + * @since 3.3 + */ +public abstract class ElementContentProvider implements IElementContentProvider { + + protected static final Object[] EMPTY = new Object[0]; + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider#updateChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext, org.eclipse.debug.internal.ui.viewers.model.provisional.IElementRequestMonitor) + */ + public void update(final IChildrenUpdate update) { + Job job = new Job("children update") { //$NON-NLS-1$ + protected IStatus run(IProgressMonitor monitor) { + if (!update.isCanceled()) { + retrieveChildren(update); + } + update.done(); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + // TODO: rule + job.schedule(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider#update(org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate) + */ + public void update(final IChildrenCountUpdate update) { + Job job = new Job("child count update") { //$NON-NLS-1$ + protected IStatus run(IProgressMonitor monitor) { + if (!update.isCanceled()) { + retrieveChildCount(update); + } + update.done(); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + // TODO: rule + job.schedule(); + } + + /** + * Computes the children for the given parent in the specified context. + * + * @param update update request + */ + protected void retrieveChildren(IChildrenUpdate update) { + if (!update.isCanceled()) { + IStatus status = Status.OK_STATUS; + try { + IPresentationContext context = update.getPresentationContext(); + if (supportsContext(context)) { + int offset = update.getOffset(); + Object parent = update.getElement(update.getParent()); + if (parent == null) { + update.setCanceled(true); + } else { + Object[] children = getChildren(parent, offset, update.getLength(), context, update); + if (!update.isCanceled() && children != null) { + for (int i = 0; i < children.length; i++) { + update.setChild(children[i], offset + i); + } + } + } + } + } catch (CoreException e) { + status = e.getStatus(); + } + update.setStatus(status); + } + } + + /** + * Computes whether the given element is a container. + * + * @param parent potential parent + * @param context presentation context + * @param monitor result to report to + */ + protected void retrieveChildCount(IChildrenCountUpdate update) { + if (!update.isCanceled()) { + IStatus status = Status.OK_STATUS; + try { + IPresentationContext context = update.getPresentationContext(); + TreePath[] parents = update.getParents(); + if (supportsContext(context)) { + for (int i = 0; i < parents.length; i++) { + Object parent = update.getElement(parents[i]); + if (parent == null) { + // viewer input changed to null + update.setCanceled(true); + break; + } + int childCount = getChildCount(parent, context, update); + if (update.isCanceled()) { + break; + } else { + update.setChildCount(parents[i], childCount); + } + } + } else { + for (int i = 0; i < parents.length; i++) { + update.setChildCount(parents[i], 0); + } + } + } catch (CoreException e) { + status = e.getStatus(); + } + update.setStatus(status); + } + } + + /** + * Returns the children for the given parent at the specified index in the specified context + * or <code>null</code> if none. + * + * @param parent element to retrieve children for + * @param index child index + * @param length number of children to retrieve + * @param context context children will be presented in + * @return child or <code>null</code> + * @throws CoreException if an exception occurs retrieving child + */ + protected abstract Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IProgressMonitor monitor) throws CoreException; + + /** + * Returns the number of children for the given element. + * + * @param element element that may have children + * @param context context element will be presented in + * @return number of children + * @throws CoreException if an exception occurs determining child count + */ + protected abstract int getChildCount(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException; + + /** + * Returns whether this adapter supports the given context. + * + * @param context + * @return whether this adapter supports the given context + */ + protected boolean supportsContext(IPresentationContext context) { + return supportsContextId(context.getId()); + } + + /** + * Returns whether this adapter provides content in the specified context id. + * + * @param id part id + * @return whether this adapter provides content in the specified context id + */ + protected abstract boolean supportsContextId(String id); + + /** + * Returns the element at the given index or <code>null</code> if none. + * + * @param elements + * @param index + * @return element or <code>null</code> + */ + protected Object[] getElements(Object[] elements, int index, int length) { + int max = elements.length; + if (index < max && ((index + length) > max)) { + length = max - index; + } + if ((index + length) <= elements.length) { + Object[] sub = new Object[length]; + System.arraycopy(elements, index, sub, 0, length); + return sub; + } + return null; + } + + public void update(final IHasChildrenUpdate update) { + Job job = new Job("has children update") { //$NON-NLS-1$ + protected IStatus run(IProgressMonitor monitor) { + if (!monitor.isCanceled()) { + updateHasChildren(update); + } + update.done(); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + // TODO: rule + job.schedule(); + } + + /** + * Updates whether the given elements have children. + * + * @param update specifies element and progress monitor + */ + protected void updateHasChildren(IHasChildrenUpdate update) { + if (!update.isCanceled()) { + IStatus status = Status.OK_STATUS; + try { + IPresentationContext context = update.getPresentationContext(); + TreePath[] elements = update.getElements(); + if (supportsContext(context)) { + for (int i = 0; i < elements.length; i++) { + Object element = update.getElement(elements[i]); + boolean hasChildren = hasChildren(element, context, update); + if (!update.isCanceled()) { + update.setHasChilren(elements[i], hasChildren); + } + } + } else { + for (int i = 0; i < elements.length; i++) { + update.setHasChilren(elements[i], false); + } + } + } catch (CoreException e) { + status = e.getStatus(); + } + update.setStatus(status); + update.done(); + } + + } + + /** + * Returns whether the given element has children in the specified context. + * Subclasses can override to be more efficient. + * + * @param element + * @param context + * @param monitor + * @return + */ + protected boolean hasChildren(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return getChildCount(element, context, monitor) > 0; + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ElementLabelProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ElementLabelProvider.java new file mode 100644 index 000000000..9bd2ab90f --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ElementLabelProvider.java @@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import java.util.LinkedList; +import java.util.NoSuchElementException; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.ui.progress.UIJob; + +/** + * @since 3.3 + */ +public abstract class ElementLabelProvider implements IElementLabelProvider { + + private Job fLabelJob = null; + + interface ILabelJob { + /** + * Returns whether the update was queued. + * + * @param update update + * @return whether the update was queued + */ + public boolean queue(ILabelUpdate update); + } + + class LabelJob extends Job implements ILabelJob { + + private LabelUpdater fUpdater = new LabelUpdater(); + + public LabelJob() { + super("Label Job"); //$NON-NLS-1$ + setSystem(true); + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + protected IStatus run(IProgressMonitor monitor) { + fUpdater.run(); + return Status.OK_STATUS; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider.ILabelJob#queue(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate) + */ + public boolean queue(ILabelUpdate update) { + return fUpdater.queue(update); + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#shouldRun() + */ + public boolean shouldRun() { + return fUpdater.shouldRun(); + } + + } + + class UILabelJob extends UIJob implements ILabelJob { + + private LabelUpdater fUpdater = new LabelUpdater(); + + public UILabelJob() { + super("Label Job"); //$NON-NLS-1$ + setSystem(true); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) + */ + public IStatus runInUIThread(IProgressMonitor monitor) { + fUpdater.run(); + return Status.OK_STATUS; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider.ILabelJob#queue(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate) + */ + public boolean queue(ILabelUpdate update) { + return fUpdater.queue(update); + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#shouldRun() + */ + public boolean shouldRun() { + return fUpdater.shouldRun(); + } + } + + /** + * Queue of label updates + */ + class LabelUpdater implements Runnable { + + LinkedList fQueue = new LinkedList(); + + public synchronized boolean queue(ILabelUpdate update) { + if (fQueue == null) { + return false; + } else { + fQueue.addLast(update); + return true; + } + } + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void run() { + ILabelUpdate update = getNextUpdate(); + while (update != null) { + try { + retrieveLabel(update); + } catch (CoreException e) { + update.setStatus(e.getStatus()); + } + update.done(); + update = getNextUpdate(); + } + } + + public synchronized ILabelUpdate getNextUpdate() { + if (fQueue == null) { + return null; + } + ILabelUpdate update = null; + try { + update = (ILabelUpdate) fQueue.removeFirst(); + } catch (NoSuchElementException e) { + fQueue = null; + } + return update; + } + + public boolean shouldRun() { + return fQueue != null; + } + } + + /** + * Retrieves label attributes for the specified update. + * + * @param update + */ + protected void retrieveLabel(ILabelUpdate update) throws CoreException { + String[] columnIds = update.getColumnIds(); + IPresentationContext presentationContext = update.getPresentationContext(); + Object element = update.getElement(); + int numColumns = 1; + if (columnIds != null) { + numColumns = columnIds.length; + } + for (int i = 0; i < numColumns; i++) { + String columnId = null; + if (columnIds != null) { + columnId = columnIds[i]; + } + update.setLabel(getLabel(element, presentationContext, columnId), i); + update.setImageDescriptor(getImageDescriptor(element, presentationContext, columnId), i); + update.setBackground(getBackground(element, presentationContext, columnId), i); + update.setForeground(getForeground(element, presentationContext, columnId), i); + update.setFontData(getFontData(element, presentationContext, columnId), i); + } + } + + /** + * @param element + * @param presentationContext + * @param columnId + * @return font information or <code>null</code> + */ + protected FontData getFontData(Object element, IPresentationContext presentationContext, String columnId) throws CoreException { + return null; + } + + /** + * @param element + * @param presentationContext + * @param columnId + * @return color or <code>null</code> + */ + protected RGB getForeground(Object element, IPresentationContext presentationContext, String columnId) throws CoreException { + return null; + } + + /** + * @param element + * @param presentationContext + * @param columnId + * @return color or <code>null</code> + */ + protected RGB getBackground(Object element, IPresentationContext presentationContext, String columnId) throws CoreException { + return null; + } + + /** + * @param element + * @param presentationContext + * @param columnId + * @return image descriptor or <code>null</code> + */ + protected ImageDescriptor getImageDescriptor(Object element, IPresentationContext presentationContext, String columnId) throws CoreException { + return null; + } + + /** + * @param element + * @param presentationContext + * @param columnId + * @return label + */ + protected abstract String getLabel(Object element, IPresentationContext presentationContext, String columnId) throws CoreException; + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider#updateLabel(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate) + */ + public synchronized void update(ILabelUpdate update) { + if (fLabelJob == null) { + fLabelJob = newLabelJob(update); + } + if (!((ILabelJob)fLabelJob).queue(update)) { + fLabelJob = newLabelJob(update); + ((ILabelJob)fLabelJob).queue(update); + } + // TODO: rule + fLabelJob.schedule(); + } + + private Job newLabelJob(ILabelUpdate update) { + if (requiresUIJob(update)) { + return new UILabelJob(); + } else { + return new LabelJob(); + } + } + + /** + * Returns whether a UI job should be used for updates versus a non-UI job. + */ + protected boolean requiresUIJob(ILabelUpdate update) { + return false; + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ElementMementoProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ElementMementoProvider.java new file mode 100644 index 000000000..7ca49fe0c --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ElementMementoProvider.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest; +import org.eclipse.ui.IMemento; + +/** + * @since 3.3 + */ +public abstract class ElementMementoProvider implements IElementMementoProvider { + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider#compareElement(org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest) + */ + public void compareElement(final IElementCompareRequest request) { + Job job = new Job("compare element") { //$NON-NLS-1$ + protected IStatus run(IProgressMonitor monitor) { + Object element = request.getElement(); + IMemento memento = request.getMemento(); + try { + request.setEqual(isEqual(element, memento)); + } catch (CoreException e) { + request.setStatus(e.getStatus()); + } + request.done(); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + // TODO: rule + job.schedule(); + } + + /** + * Returns whether the memento represents the given element. + * + * @param element + * @param memento + * @return whether the memento represents the given element + */ + protected abstract boolean isEqual(Object element, IMemento memento) throws CoreException; + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider#encodeElement(org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest) + */ + public void encodeElement(final IElementMementoRequest request) { + Job job = new Job("encode element") { //$NON-NLS-1$ + protected IStatus run(IProgressMonitor monitor) { + Object element = request.getElement(); + IMemento memento = request.getMemento(); + try { + if (!encodeElement(element, memento)) { + request.setCanceled(true); + } + } catch (CoreException e) { + request.setStatus(e.getStatus()); + } + request.done(); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + // TODO: rule + job.schedule(); + } + + /** + * Encodes the specified element into the given memento. + * Returns whether the element could be encoded + * + * @param element + * @param memento + * @return false if cancelled/not supported + * @throws CoreException + */ + protected abstract boolean encodeElement(Object element, IMemento memento) throws CoreException; + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ExpressionContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ExpressionContentProvider.java new file mode 100644 index 000000000..f78a5f3b6 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ExpressionContentProvider.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.model.IErrorReportingExpression; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + +/** + * @since 3.3 + */ +public class ExpressionContentProvider extends VariableContentProvider { + + protected Object[] getAllChildren(Object parent, IPresentationContext context) throws CoreException { + if (parent instanceof IErrorReportingExpression) { + IErrorReportingExpression expression = (IErrorReportingExpression) parent; + if (expression.hasErrors()) { + return expression.getErrorMessages(); + } + } + if (parent instanceof IExpression) { + IExpression expression = (IExpression) parent; + IValue value = expression.getValue(); + if (value != null) { + return getValueChildren(expression, value, context); + } + } + return EMPTY; + } + + protected boolean hasChildren(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + if (element instanceof IErrorReportingExpression) { + IErrorReportingExpression expression = (IErrorReportingExpression) element; + if (expression.hasErrors()) { + return true; + } + } + IValue value = ((IExpression)element).getValue(); + if (value == null) { + return false; + } + return value.hasVariables(); + } +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ExpressionLabelProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ExpressionLabelProvider.java new file mode 100644 index 000000000..6d4e87eb5 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ExpressionLabelProvider.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.model.IErrorReportingExpression; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.swt.graphics.RGB; + +/** + * @since 3.3 + */ +public class ExpressionLabelProvider extends VariableLabelProvider { + + protected RGB getForeground(Object element, IPresentationContext presentationContext, String columnId) throws CoreException { + if (element instanceof IErrorReportingExpression) { + IErrorReportingExpression expression = (IErrorReportingExpression) element; + if (expression.hasErrors()) { + return new RGB(255, 0, 0); + } + } + return super.getForeground(element, presentationContext, columnId); + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ExpressionManagerContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ExpressionManagerContentProvider.java new file mode 100644 index 000000000..fe2f1bafc --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ExpressionManagerContentProvider.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.IExpressionManager; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.IDebugUIConstants; + +/** + * + */ +public class ExpressionManagerContentProvider extends ElementContentProvider { + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected int getChildCount(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return ((IExpressionManager) element).getExpressions().length; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return ((IExpressionManager) parent).getExpressions(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#supportsContextId(java.lang.String) + */ + protected boolean supportsContextId(String id) { + return id.equals(IDebugUIConstants.ID_EXPRESSION_VIEW); + } + + protected boolean hasChildren(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return ((IExpressionManager)element).hasExpressions(); + } + + + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/LaunchContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/LaunchContentProvider.java new file mode 100644 index 000000000..b6bcbeedd --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/LaunchContentProvider.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.IDebugUIConstants; + +/** + * @since 3.3 + */ +public class LaunchContentProvider extends ElementContentProvider { + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected int getChildCount(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return ((ILaunch)element).getChildren().length; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#supportsContextId(java.lang.String) + */ + protected boolean supportsContextId(String id) { + return IDebugUIConstants.ID_DEBUG_VIEW.equals(id); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return getElements(((ILaunch)parent).getChildren(), index, length); + } + + protected boolean hasChildren(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return ((ILaunch)element).hasChildren(); + } + + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/LaunchManagerContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/LaunchManagerContentProvider.java new file mode 100644 index 000000000..6114958a6 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/LaunchManagerContentProvider.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.IDebugUIConstants; + +/** + * @since 3.3 + */ +public class LaunchManagerContentProvider extends ElementContentProvider { + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected int getChildCount(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return ((ILaunchManager)element).getLaunches().length; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#supportsContextId(java.lang.String) + */ + protected boolean supportsContextId(String id) { + return IDebugUIConstants.ID_DEBUG_VIEW.equals(id); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return getElements(((ILaunchManager)parent).getLaunches(),index, length); + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/StackFrameContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/StackFrameContentProvider.java new file mode 100644 index 000000000..c66035ac9 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/StackFrameContentProvider.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.IDebugUIConstants; + +/** + * @since 3.3 + */ +public class StackFrameContentProvider extends ElementContentProvider { + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected int getChildCount(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return getAllChildren(element, context, monitor).length; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return getElements(getAllChildren(parent, context, monitor), index, length); + } + + protected Object[] getAllChildren(Object parent, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + String id = context.getId(); + IStackFrame frame = (IStackFrame) parent; + if (id.equals(IDebugUIConstants.ID_VARIABLE_VIEW)) { + return frame.getVariables(); + } else if (id.equals(IDebugUIConstants.ID_REGISTER_VIEW)) { + return frame.getRegisterGroups(); + } + return EMPTY; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#supportsContextId(java.lang.String) + */ + protected boolean supportsContextId(String id) { + return id.equals(IDebugUIConstants.ID_VARIABLE_VIEW) || id.equals(IDebugUIConstants.ID_REGISTER_VIEW); + } + + protected boolean hasChildren(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + String id = context.getId(); + IStackFrame frame = (IStackFrame) element; + if (id.equals(IDebugUIConstants.ID_VARIABLE_VIEW)) { + return frame.hasVariables(); + } else if (id.equals(IDebugUIConstants.ID_REGISTER_VIEW)) { + return frame.hasRegisterGroups(); + } + return false; + } + + + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ThreadContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ThreadContentProvider.java new file mode 100644 index 000000000..facff78be --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/ThreadContentProvider.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.model.IThread; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.IDebugUIConstants; + +/** + * @since 3.3 + */ +public class ThreadContentProvider extends ElementContentProvider { + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected int getChildCount(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return ((IThread)element).getStackFrames().length; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#supportsContextId(java.lang.String) + */ + protected boolean supportsContextId(String id) { + return IDebugUIConstants.ID_DEBUG_VIEW.equals(id); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return getElements(((IThread)parent).getStackFrames(), index, length); + } + + protected boolean hasChildren(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return ((IThread)element).hasStackFrames(); + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/VariableContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/VariableContentProvider.java new file mode 100644 index 000000000..3518a4243 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/VariableContentProvider.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILogicalStructureType; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IIndexedValue; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.model.IVariable; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.views.variables.IndexedVariablePartition; +import org.eclipse.debug.internal.ui.views.variables.VariablesView; +import org.eclipse.debug.ui.IDebugUIConstants; + +/** + * @since 3.3 + */ +public class VariableContentProvider extends ElementContentProvider { + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected int getChildCount(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return getAllChildren(element, context).length; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return getElements(getAllChildren(parent, context), index, length); + } + + protected Object[] getAllChildren(Object parent, IPresentationContext context) throws CoreException { + IVariable variable = (IVariable) parent; + IValue value = variable.getValue(); + if (value != null) { + return getValueChildren(variable, value, context); + } + return EMPTY; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#supportsContextId(java.lang.String) + */ + protected boolean supportsContextId(String id) { + return id.equals(IDebugUIConstants.ID_EXPRESSION_VIEW) || id.equals(IDebugUIConstants.ID_VARIABLE_VIEW) || id.equals(IDebugUIConstants.ID_REGISTER_VIEW); + } + + /** + * Return whether to show compute a logical structure or a raw structure + * in the specified context + * + * @return whether to show compute a logical structure or a raw structure + * in the specified context + */ + protected boolean isShowLogicalStructure(IPresentationContext context) { + Boolean show = (Boolean) context.getProperty(VariablesView.PRESENTATION_SHOW_LOGICAL_STRUCTURES); + return show != null && show.booleanValue(); + } + + /** + * Returns the number of entries that should be displayed in each partition + * of an indexed collection. + * + * @return the number of entries that should be displayed in each partition + * of an indexed collection + */ + protected int getArrayPartitionSize() { + // TODO: should fix this with a user preference + return 100; + } + + /** + * Returns any logical value for the raw value in the specified context + * + * @param value + * @param context + * @return + */ + protected IValue getLogicalValue(IValue value, IPresentationContext context) { + return getLogicalValue(value, new ArrayList(), context); + } + + /** + * Returns children for the given value, creating array partitions if + * required + * + * @param parent expression or variable containing the given value + * @param value the value to retrieve children for + * @param context the context in which children have been requested + * @return children for the given value, creating array partitions if + * required + * @throws CoreException + */ + protected Object[] getValueChildren(IDebugElement parent, IValue value, IPresentationContext context) throws CoreException { + if (value == null) { + return EMPTY; + } + IValue logicalValue = getLogicalValue(value, context); + if (logicalValue instanceof IIndexedValue) { + IIndexedValue indexedValue = (IIndexedValue) logicalValue; + int partitionSize = computeParitionSize(indexedValue); + if (partitionSize > 1) { + int offset = indexedValue.getInitialOffset(); + int length = indexedValue.getSize(); + int numPartitions = length / partitionSize; + int remainder = length % partitionSize; + if (remainder > 0) { + numPartitions++; + } + IVariable[] partitions = new IVariable[numPartitions]; + for (int i = 0; i < (numPartitions - 1); i++) { + partitions[i] = new IndexedVariablePartition(parent, indexedValue, offset, partitionSize); + offset = offset + partitionSize; + } + if (remainder == 0) { + remainder = partitionSize; + } + partitions[numPartitions - 1] = new IndexedVariablePartition(parent, indexedValue, offset, remainder); + return partitions; + } + } + if (logicalValue == null) { + // safeguard against an structure type returning null + logicalValue = value; + } + return logicalValue.getVariables(); + } + + /** + * Returns the partition size to use for the given indexed value. The + * partition size is computed by determining the number of levels that an + * indexed collection must be nested in order to partition the collection + * sub-collections of the preferred partition size. + * + * @param value + * indexed value + * @return size of paritions the value should be subdivided into + */ + protected int computeParitionSize(IIndexedValue value) { + int partitionSize = 1; + try { + int length = value.getSize(); + int partitionDepth = 0; + int preferredSize = getArrayPartitionSize(); + int remainder = length % preferredSize; + length = length / preferredSize; + while (length > 0) { + if (remainder == 0 && length == 1) { + break; + } + partitionDepth++; + remainder = length % preferredSize; + length = length / preferredSize; + } + for (int i = 0; i < partitionDepth; i++) { + partitionSize = partitionSize * preferredSize; + } + } catch (DebugException e) { + } + return partitionSize; + } + + /** + * Returns any logical value for the raw value. This method will recurse + * over the returned value until the same structure is encountered again (to + * avoid infinite recursion). + * + * @param value + * @param previousStructureIds + * the list of logical structures that have already been applied + * to the returned value during the recursion of this method. + * Callers should always pass in a new, empty list. + * @return + */ + protected IValue getLogicalValue(IValue value, List previousStructureIds, IPresentationContext context) { + if (isShowLogicalStructure(context)) { + ILogicalStructureType[] types = DebugPlugin.getLogicalStructureTypes(value); + if (types.length > 0) { + ILogicalStructureType type = DebugPlugin.getDefaultStructureType(types); + if (type != null && !previousStructureIds.contains(type.getId())) { + try { + value = type.getLogicalStructure(value); + previousStructureIds.add(type.getId()); + return getLogicalValue(value, previousStructureIds, context); + } catch (CoreException e) { + // unable to display logical structure + } + } + } + } + return value; + } + + protected boolean hasChildren(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return ((IVariable)element).getValue().hasVariables(); + } + + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/VariableEditor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/VariableEditor.java new file mode 100644 index 000000000..b886d20ed --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/VariableEditor.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.debug.internal.ui.elements.adapters.DefaultVariableCellModifier; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.swt.widgets.Composite; + +/** + * @since 3.3 + */ +public class VariableEditor implements IElementEditor { + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor#getCellEditor(org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, java.lang.String, java.lang.Object, org.eclipse.swt.widgets.Composite) + */ + public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) { + return new TextCellEditor(parent); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor#getCellModifier(org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, java.lang.Object) + */ + public ICellModifier getCellModifier(IPresentationContext context, Object element) { + return new DefaultVariableCellModifier(); + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/VariableLabelProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/VariableLabelProvider.java new file mode 100644 index 000000000..8c149fa92 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/VariableLabelProvider.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.model.IVariable; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.DefaultLabelProvider; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; +import org.eclipse.debug.internal.ui.elements.adapters.VariableColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.RGB; + +/** + * @since 3.3 + */ +public class VariableLabelProvider extends DebugElementLabelProvider { + + protected RGB getBackground(Object element, IPresentationContext presentationContext, String columnId) throws CoreException { + if (columnId != null) { + if (element instanceof IVariable) { + IVariable variable = (IVariable) element; + if (variable.hasValueChanged()) { + return DebugUIPlugin.getPreferenceColor(IInternalDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND).getRGB(); + } + } + } + return super.getBackground(element, presentationContext, columnId); + } + + protected RGB getForeground(Object element, IPresentationContext presentationContext, String columnId) throws CoreException { + if (columnId == null) { + if (element instanceof IVariable) { + IVariable variable = (IVariable) element; + if (variable.hasValueChanged()) { + return DebugUIPlugin.getPreferenceColor(IDebugUIConstants.PREF_CHANGED_DEBUG_ELEMENT_COLOR).getRGB(); + } + } + } + return super.getForeground(element, presentationContext, columnId); + } + + protected ImageDescriptor getImageDescriptor(Object element, IPresentationContext presentationContext, String columnId) throws CoreException { + if (columnId == null || VariableColumnPresentation.COLUMN_VARIABLE_NAME.equals(columnId)) { + return super.getImageDescriptor(element, presentationContext, columnId); + } + return null; + } + + protected String getLabel(Object element, IPresentationContext context, String columnId) throws CoreException { + if (columnId == null) { + return escapeSpecialChars(super.getLabel(element, context, columnId)); + } else { + IVariable variable = (IVariable) element; + IValue value = variable.getValue(); + return getColumnText(variable, value, context, columnId); + } + } + + /** + * Returns text for a specific columns for the variable/value. + * + * @param variable + * @param value + * @param context + * @param columnId + * @return + * @throws CoreException + */ + protected String getColumnText(IVariable variable, IValue value, IPresentationContext context, String columnId) throws CoreException { + if (VariableColumnPresentation.COLUMN_VARIABLE_NAME.equals(columnId)) { + return getVariableName(variable, context); + } else if (VariableColumnPresentation.COLUMN_VARIABLE_TYPE.equals(columnId)) { + return getVariableTypeName(variable, context); + } else if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(columnId)) { + return getValueText(variable, value, context); + } else if (VariableColumnPresentation.COLUMN_VALUE_TYPE.equals(columnId)) { + return getValueTypeName(variable, value, context); + } + return null; + } + + /** + * Returns the name of the given variable to display in <code>COLUMN_VARIABLE_NAME</code>. + * + * @param variable + * @return variable name + * @throws CoreException + */ + protected String getVariableName(IVariable variable, IPresentationContext context) throws CoreException { + return variable.getName(); + } + + /** + * Returns the type name of the given variable to display in <code>COLUMN_VARIABLE_TYPE</code>. + * + * @param variable + * @return variable type name + * @throws CoreException + */ + protected String getVariableTypeName(IVariable variable, IPresentationContext context) throws CoreException { + return variable.getReferenceTypeName(); + } + + /** + * Returns the label for the given value's type to display in <code>COLUMN_VARIABLE_VALUE</code> + * + * @param variable + * @param value + * @return value label + * @throws CoreException + */ + protected String getValueTypeName(IVariable variable, IValue value, IPresentationContext context) throws CoreException { + return value.getReferenceTypeName(); + } + + /** + * Returns the label for the given value to display in <code>COLUMN_VALUE_TYPE</code> + * + * @param variable + * @param value + * @return value label + * @throws CoreException + */ + protected String getValueText(IVariable variable, IValue value, IPresentationContext context) throws CoreException { + return escapeSpecialChars(value.getValueString()); + } + + protected String escapeSpecialChars(String label) { + return DefaultLabelProvider.escapeSpecialChars(label); + } +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/VariablesViewElementMementoProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/VariablesViewElementMementoProvider.java new file mode 100644 index 000000000..9e51161e6 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/VariablesViewElementMementoProvider.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.model.elements; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.debug.core.model.IVariable; +import org.eclipse.ui.IMemento; + +/** + * @since 3.3 + */ +public class VariablesViewElementMementoProvider extends ElementMementoProvider { + + /** + * memento attribute + */ + private static final String ELEMENT_NAME = "ELEMENT_NAME"; //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementMementoProvider#encodeElement(java.lang.Object, org.eclipse.ui.IMemento) + */ + protected boolean encodeElement(Object element, IMemento memento) throws CoreException { + if (element instanceof IStackFrame) { + IStackFrame frame = (IStackFrame) element; + memento.putString(ELEMENT_NAME, frame.getName()); + } else if (element instanceof IVariable) { + IVariable variable = (IVariable) element; + memento.putString(ELEMENT_NAME, variable.getName()); + } else { + return false; + } + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementMementoProvider#isEqual(java.lang.Object, org.eclipse.ui.IMemento) + */ + protected boolean isEqual(Object element, IMemento memento) throws CoreException { + String mementoName = memento.getString(ELEMENT_NAME); + if (mementoName != null) { + String elementName = null; + if (element instanceof IStackFrame) { + IStackFrame frame = (IStackFrame) element; + elementName = frame.getName(); + } else if (element instanceof IVariable) { + IVariable variable = (IVariable) element; + elementName = variable.getName(); + } + if (elementName != null) { + return elementName.equals(mementoName); + } + } + return false; + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousModel.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousModel.java index 231f73275..91e90cf70 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousModel.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousModel.java @@ -25,14 +25,14 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.elements.adapters.AsynchronousDebugLabelAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; 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.ILabelRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxyFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.ui.commands.IStatusMonitor; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.jface.viewers.ViewerSorter; @@ -190,7 +190,7 @@ public abstract class AsynchronousModel { if (!monitor.isCanceled()) { proxy.init(getPresentationContext()); getViewer().modelProxyAdded(proxy); - proxy.installed(); + proxy.installed(getViewer()); } return Status.OK_STATUS; } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousSchedulingRuleFactory.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousSchedulingRuleFactory.java index d8c1e421c..5a9218c18 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousSchedulingRuleFactory.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousSchedulingRuleFactory.java @@ -11,7 +11,6 @@ package org.eclipse.debug.internal.ui.viewers; import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; /** * Scheduling rule factory for asycn operations. @@ -97,15 +96,4 @@ public class AsynchronousSchedulingRuleFactory { return new SerialPerObjectRule(lock); } - /** - * Returns a scheduling rule that allows all jobs with an instance of - * the rule to run one at a time per part associated with the given - * presentation context. - * - * @param context presentation context - * @return scheduling rule - */ - public ISchedulingRule newSerialPerPartRule(IPresentationContext context) { - return newSerialPerObjectRule(context.getPart()); - } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableModel.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableModel.java index 904fa021a..98b70f24d 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableModel.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableModel.java @@ -31,7 +31,7 @@ public class AsynchronousTableModel extends AsynchronousModel { } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModel#add(org.eclipse.debug.internal.ui.model.viewers.ModelNode, java.lang.Object) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousModel#add(org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelNode, java.lang.Object) */ protected void add(ModelNode parent, Object element) {} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewer.java index 2ba1e2586..e2854a629 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewer.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewer.java @@ -161,7 +161,7 @@ public class AsynchronousTableViewer extends AsynchronousViewer implements Liste } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousViewer#internalRefresh(org.eclipse.debug.internal.ui.model.viewers.ModelNode) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousViewer#internalRefresh(org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelNode) */ protected void internalRefresh(ModelNode node) { super.internalRefresh(node); @@ -429,14 +429,14 @@ public class AsynchronousTableViewer extends AsynchronousViewer implements Liste } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousViewer#createModel() + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousViewer#createModel() */ protected AsynchronousModel createModel() { return new AsynchronousTableModel(this); } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousViewer#setItemCount(org.eclipse.swt.widgets.Widget, int) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousViewer#setItemCount(org.eclipse.swt.widgets.Widget, int) */ protected void setItemCount(Widget parent, int itemCount) { fTable.setItemCount(itemCount); @@ -448,14 +448,14 @@ public class AsynchronousTableViewer extends AsynchronousViewer implements Liste } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousViewer#createUpdatePolicy() + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousViewer#createUpdatePolicy() */ public AbstractUpdatePolicy createUpdatePolicy() { return new TableUpdatePolicy(); } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousViewer#getParentWidget(org.eclipse.swt.widgets.Widget) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousViewer#getParentWidget(org.eclipse.swt.widgets.Widget) */ protected Widget getParentWidget(Widget widget) { if (widget instanceof TableItem) { @@ -465,7 +465,7 @@ public class AsynchronousTableViewer extends AsynchronousViewer implements Liste } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousViewer#getChildWidget(org.eclipse.swt.widgets.Widget, int) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousViewer#getChildWidget(org.eclipse.swt.widgets.Widget, int) */ protected Widget getChildWidget(Widget parent, int index) { if (index < fTable.getItemCount()) { @@ -475,7 +475,7 @@ public class AsynchronousTableViewer extends AsynchronousViewer implements Liste } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousViewer#clear(org.eclipse.swt.widgets.Widget) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousViewer#clear(org.eclipse.swt.widgets.Widget) */ protected void clear(Widget item) { if (item instanceof TableItem) { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeViewer.java index 993f0874d..eb7771a27 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeViewer.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeViewer.java @@ -23,11 +23,12 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; 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.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.DoubleClickEvent; @@ -806,7 +807,7 @@ public class AsynchronousTreeViewer extends AsynchronousViewer { } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousViewer#setItemCount(org.eclipse.swt.widgets.Widget, int) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousViewer#setItemCount(org.eclipse.swt.widgets.Widget, int) */ protected void setItemCount(Widget widget, int itemCount) { if (widget == fTree) { @@ -817,7 +818,7 @@ public class AsynchronousTreeViewer extends AsynchronousViewer { } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousViewer#getChildWidget(org.eclipse.swt.widgets.Widget, int) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousViewer#getChildWidget(org.eclipse.swt.widgets.Widget, int) */ protected Widget getChildWidget(Widget parent, int index) { if (parent instanceof Tree) { @@ -879,7 +880,7 @@ public class AsynchronousTreeViewer extends AsynchronousViewer { } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousViewer#clear(org.eclipse.swt.widgets.Widget) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousViewer#clear(org.eclipse.swt.widgets.Widget) */ protected void clear(Widget widget) { if (DEBUG_VIEWER) { @@ -974,7 +975,7 @@ public class AsynchronousTreeViewer extends AsynchronousViewer { } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousViewer#internalRefresh(org.eclipse.debug.internal.ui.model.viewers.ModelNode) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousViewer#internalRefresh(org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelNode) */ protected void internalRefresh(ModelNode node) { super.internalRefresh(node); @@ -1251,7 +1252,7 @@ public class AsynchronousTreeViewer extends AsynchronousViewer { } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousViewer#createUpdatePolicy() + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousViewer#createUpdatePolicy() */ public AbstractUpdatePolicy createUpdatePolicy() { return new TreeUpdatePolicy(); diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java index 1e0e50a51..04aae5b66 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java @@ -22,11 +22,12 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.debug.internal.ui.DebugUIPlugin; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelSelectionPolicy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelSelectionPolicyFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicyFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext; import org.eclipse.debug.ui.commands.IStatusMonitor; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ISelection; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/PartPresentationContext.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/PartPresentationContext.java new file mode 100644 index 000000000..9ecf2ee7a --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/PartPresentationContext.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext; +import org.eclipse.ui.IWorkbenchPart; + +/** + * A presentation context tied to a part. + * + * @since 3.3 + */ +public class PartPresentationContext extends PresentationContext { + + private IWorkbenchPart fPart; + + /** + * Constructs a part presentation context. + * + * @param part part + */ + public PartPresentationContext(IWorkbenchPart part) { + super(part.getSite().getId()); + fPart = part; + } + + public IWorkbenchPart getPart() { + return fPart; + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableAddRequestMonitor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableAddRequestMonitor.java index 0151bac98..360186c45 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableAddRequestMonitor.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableAddRequestMonitor.java @@ -29,14 +29,14 @@ public class TableAddRequestMonitor extends AsynchronousRequestMonitor { } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousRequestMonitor#performUpdate() + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousRequestMonitor#performUpdate() */ protected void performUpdate() { ((AsynchronousTableModel)getModel()).added(fElements); } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousRequestMonitor#contains(org.eclipse.debug.internal.ui.model.viewers.AsynchronousRequestMonitor) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousRequestMonitor#contains(org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousRequestMonitor) */ protected boolean contains(AsynchronousRequestMonitor update) { return false; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableInsertRequestMonitor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableInsertRequestMonitor.java index 4761941ed..57f15cdd4 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableInsertRequestMonitor.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableInsertRequestMonitor.java @@ -29,7 +29,7 @@ public class TableInsertRequestMonitor extends TableAddRequestMonitor { } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousRequestMonitor#performUpdate() + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousRequestMonitor#performUpdate() */ protected void performUpdate() { ((AsynchronousTableModel)getModel()).inserted(fElements, fIndex); diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableRemoveRequestMonitor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableRemoveRequestMonitor.java index e1fe7b085..421ade779 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableRemoveRequestMonitor.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableRemoveRequestMonitor.java @@ -27,7 +27,7 @@ public class TableRemoveRequestMonitor extends TableAddRequestMonitor { } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousRequestMonitor#performUpdate() + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousRequestMonitor#performUpdate() */ protected void performUpdate() { ((AsynchronousTableModel)getModel()).removed(fElements); diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableReplaceRequestMonitor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableReplaceRequestMonitor.java index ae6a8594e..ca66b8696 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableReplaceRequestMonitor.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableReplaceRequestMonitor.java @@ -31,14 +31,14 @@ public class TableReplaceRequestMonitor extends AsynchronousRequestMonitor { } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousRequestMonitor#performUpdate() + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousRequestMonitor#performUpdate() */ protected void performUpdate() { ((AsynchronousTableModel)getModel()).replaced(fOriginal, fReplacement); } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousRequestMonitor#contains(org.eclipse.debug.internal.ui.model.viewers.AsynchronousRequestMonitor) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousRequestMonitor#contains(org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousRequestMonitor) */ protected boolean contains(AsynchronousRequestMonitor update) { return false; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableUpdatePolicy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableUpdatePolicy.java index 4e81f8631..b3f176362 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableUpdatePolicy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableUpdatePolicy.java @@ -10,8 +10,9 @@ *******************************************************************************/ package org.eclipse.debug.internal.ui.viewers; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; import org.eclipse.jface.viewers.StructuredSelection; /** @@ -21,7 +22,7 @@ import org.eclipse.jface.viewers.StructuredSelection; */ public class TableUpdatePolicy extends org.eclipse.debug.internal.ui.viewers.AbstractUpdatePolicy implements IModelChangedListener { - public void modelChanged(IModelDelta delta) { + public void modelChanged(IModelDelta delta, IModelProxy proxy) { updateNodes(new IModelDelta[] {delta}); } @@ -75,7 +76,7 @@ public class TableUpdatePolicy extends org.eclipse.debug.internal.ui.viewers.Abs handleInsert(node); } - IModelDelta[] childNodes = node.getNodes(); + IModelDelta[] childNodes = node.getChildDeltas(); updateNodes(childNodes); } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TreeUpdatePolicy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TreeUpdatePolicy.java index 2f1a31ad0..d98b904d7 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TreeUpdatePolicy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TreeUpdatePolicy.java @@ -12,8 +12,9 @@ package org.eclipse.debug.internal.ui.viewers; import java.util.ArrayList; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeSelection; @@ -28,7 +29,7 @@ public class TreeUpdatePolicy extends AbstractUpdatePolicy implements IModelChan private TreePath fTreePath; private IModelDelta fNode; - public void modelChanged(IModelDelta delta) { + public void modelChanged(IModelDelta delta, IModelProxy proxy) { updateNodes(new IModelDelta[] { delta }); fTreePath = null; fNode = null; @@ -69,7 +70,7 @@ public class TreeUpdatePolicy extends AbstractUpdatePolicy implements IModelChan // TODO } - updateNodes(node.getNodes()); + updateNodes(node.getChildDeltas()); } } @@ -101,8 +102,8 @@ public class TreeUpdatePolicy extends AbstractUpdatePolicy implements IModelChan if (node != fNode) { ArrayList list = new ArrayList(); list.add(0, node.getElement()); - while (node.getParent() != null) { - node = node.getParent(); + while (node.getParentDelta() != null) { + node = node.getParentDelta(); list.add(0, node.getElement()); } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ChildrenCountUpdate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ChildrenCountUpdate.java new file mode 100644 index 000000000..e147153ec --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ChildrenCountUpdate.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.TreeViewer; + +/** + * @since 3.3 + */ +class ChildrenCountUpdate extends ViewerUpdateMonitor implements IChildrenCountUpdate { + + /** + * Map of <code>TreePath</code>s to <code>Integer</code>s. + */ + private Map fCounts = new HashMap(); + + /** + * Set of <code>TreePath</code>s. + */ + private Set fParents = new HashSet(); + + private boolean fStarted = false; + private IElementContentProvider fContentProvider; + + /** + * @param contentProvider + */ + public ChildrenCountUpdate(ModelContentProvider contentProvider, IElementContentProvider elementContentProvider) { + super(contentProvider); + fContentProvider = elementContentProvider; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ViewerUpdateMonitor#performUpdate() + */ + protected void performUpdate() { + Iterator iterator = fCounts.entrySet().iterator(); + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + int count = ((Integer)(entry.getValue())).intValue(); + TreePath parentPath = (TreePath) entry.getKey(); + int viewCount = count; + if (count == 0) { + getContentProvider().clearFilters(parentPath); + } else { + viewCount = getContentProvider().modelToViewChildCount(parentPath, count); + } + if (ModelContentProvider.DEBUG_CONTENT_PROVIDER) { + System.out.println("setChildCount(" + getElement(parentPath) + ", modelCount: " + count + " viewCount: " + viewCount + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + ((TreeViewer)(getContentProvider().getViewer())).setChildCount(parentPath, viewCount); + } + } + + public void setChildCount(TreePath parentPath, int numChildren) { + fCounts.put(parentPath, new Integer(numChildren)); + } + + /** + * @param element + * @return + */ + protected boolean coalesce(TreePath treePath) { + fParents.add(treePath); + return true; + } + + /** + * + */ + protected void start() { + synchronized (this) { + if (fStarted) { + return; + } + fStarted = true; + } + TreeModelContentProvider contentProvider = (TreeModelContentProvider)getContentProvider(); + contentProvider.countRequestStarted(fContentProvider); + if (!isCanceled()) { + fContentProvider.update(this); + } else { + done(); + } + } + + public TreePath[] getParents() { + return (TreePath[]) fParents.toArray(new TreePath[fParents.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.ViewerUpdateMonitor#isContained(org.eclipse.jface.viewers.TreePath) + */ + boolean isContained(TreePath path) { + return ((TreePath)fParents.iterator().next()).startsWith(path, null); + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ChildrenUpdate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ChildrenUpdate.java new file mode 100644 index 000000000..6d19aa839 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ChildrenUpdate.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.jface.viewers.TreePath; + +/** + * @since 3.3 + */ +class ChildrenUpdate extends ViewerUpdateMonitor implements IChildrenUpdate { + + private TreePath fParentPath; + private Object[] fElements; + private int fIndex; + private int fLength; + private IElementContentProvider fContentProvider; + private boolean fStarted = false; + + /** + * Constructs a request to update an element + * + * @param node node to update + * @param model model containing the node + */ + public ChildrenUpdate(ModelContentProvider provider, TreePath parentPath, int index, IElementContentProvider presentation) { + super(provider); + fParentPath = parentPath; + fIndex = index; + fLength = 1; + fContentProvider = presentation; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.debug.ui.viewers.AsynchronousRequestMonitor#performUpdate() + */ + protected void performUpdate() { + TreeModelContentProvider provider = (TreeModelContentProvider) getContentProvider(); + if (fElements != null) { + InternalTreeModelViewer viewer = (InternalTreeModelViewer) provider.getViewer(); + for (int i = 0; i < fElements.length; i++) { + int modelIndex = fIndex + i; + Object element = fElements[i]; + if (element != null) { + int viewIndex = provider.modelToViewIndex(fParentPath, modelIndex); + if (provider.shouldFilter(fParentPath, element)) { + if (provider.addFilteredIndex(fParentPath, modelIndex)) { + if (ModelContentProvider.DEBUG_CONTENT_PROVIDER) { + System.out.println("REMOVE(" + getElement(fParentPath) + ", modelIndex: " + modelIndex + " viewIndex: " + viewIndex + ", " + element + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + } + viewer.remove(fParentPath, viewIndex); + } + } else { + if (provider.isFiltered(fParentPath, modelIndex)) { + provider.clearFilteredChild(fParentPath, modelIndex); + int insertIndex = provider.modelToViewIndex(fParentPath, modelIndex); + if (ModelContentProvider.DEBUG_CONTENT_PROVIDER) { + System.out.println("insert(" + fParentPath.getLastSegment() + ", modelIndex: " + modelIndex + " insertIndex: " + insertIndex + ", " + element + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + } + if (fParentPath.getSegmentCount() == 0) { + // TODO: does empty path work in viewer? + viewer.insert(getElement(fParentPath), element, insertIndex); + } else { + viewer.insert(fParentPath, element, insertIndex); + } + } else { + if (ModelContentProvider.DEBUG_CONTENT_PROVIDER) { + System.out.println("replace(" + getElement(fParentPath) + ", modelIndex: " + modelIndex + " viewIndex: " + viewIndex + ", " + element + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + } + if (fParentPath.getSegmentCount() > 0) { + viewer.replace(fParentPath, viewIndex, element); + } else { + viewer.replace(getElement(fParentPath), viewIndex, element); + } + } + TreePath childPath = fParentPath.createChildPath(element); + provider.updateHasChildren(childPath); + } + } + } + } else { + provider.updateHasChildren(fParentPath); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate#setChild(java.lang.Object, int) + */ + public void setChild(Object child, int index) { + if (fElements == null) { + fElements = new Object[fLength]; + } + fElements[index - fIndex] = child; + } + + /** + * Coalesce the request with the given index. Return whether the requests can be + * coalesced. + * + * @param index + * @return whether it worked + */ + public boolean coalesce(int index) { + if (index == fIndex + fLength) { + fLength++; + return true; + } + return false; + } + + public void start() { + synchronized (this) { + if (fStarted) { + return; + } + fStarted = true; + } + //System.out.println("\tRequest (" + fParent + "): " + fIndex + " length: " + fLength); + TreeModelContentProvider contentProvider = (TreeModelContentProvider)getContentProvider(); + contentProvider.childRequestStarted(this); + if (!isCanceled()) { + fContentProvider.update(this); + } else { + done(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate#getLength() + */ + public int getLength() { + return fLength; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate#getOffset() + */ + public int getOffset() { + return fIndex; + } + + public TreePath getParent() { + return fParentPath; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.ViewerUpdateMonitor#isContained(org.eclipse.jface.viewers.TreePath) + */ + boolean isContained(TreePath path) { + return fParentPath.startsWith(path, null); + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ElementCompareRequest.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ElementCompareRequest.java new file mode 100644 index 000000000..1dee5ccc6 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ElementCompareRequest.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.ui.IMemento; + +/** + * @since 3.3 + */ +class ElementCompareRequest extends MementoUpdate implements IElementCompareRequest { + + private boolean fEqual; + private ModelDelta fDelta; + /** + * @param context + * @param element + * @param memento + */ + public ElementCompareRequest(ModelContentProvider provider, Object element, IMemento memento, ModelDelta delta) { + super(provider, provider.getPresentationContext(), element, memento); + fProvider = provider; + fDelta = delta; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest#setEqual(boolean) + */ + public void setEqual(boolean equal) { + fEqual = equal; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IProgressMonitor#done() + */ + public void done() { + if (isEqual()) { + fDelta.setElement(getElement()); + fProvider.doRestore(fDelta); + } + } + + boolean isEqual() { + return fEqual; + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ElementMementoRequest.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ElementMementoRequest.java new file mode 100644 index 000000000..b41260f14 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ElementMementoRequest.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.ui.IMemento; + +/** + * @since 3.3 + */ +class ElementMementoRequest extends MementoUpdate implements IElementMementoRequest { + + private IMementoManager fManager; + private ModelDelta fDelta; + + /** + * @param context + * @param element + * @param memento + */ + public ElementMementoRequest(ModelContentProvider provider, IMementoManager manager, IPresentationContext context, Object element, IMemento memento, ModelDelta delta) { + super(provider, context, element, memento); + fManager = manager; + fDelta = delta; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IProgressMonitor#done() + */ + public void done() { + if (!isCanceled() && (getStatus() == null || getStatus().isOK())) { + // replace the element with a memento + fDelta.setElement(getMemento()); + } + fManager.requestComplete(this); + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/FilterTransform.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/FilterTransform.java new file mode 100644 index 000000000..03202a012 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/FilterTransform.java @@ -0,0 +1,365 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + ******************************************************************************/ + +package org.eclipse.debug.internal.ui.viewers.model; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.viewers.TreePath; + + +/** + * Helper class to support filtering in virtual tree viewer. + * Translates indexes from viewer to model coordinate space (and visa versa). + * <p> + * This filter transform maintains a tree representing filtered elements in the + * viewer. The filtering is performed dynamically as elements are 'replaced' in the tree + * by a lazy tree content provider. + * </p> + * <p> + * This class not intended to be subclassed or instantiated. For internal use only. + * </p> + * <p> + * <strong>EXPERIMENTAL</strong>. This class or interface has been added as + * part of a work in progress. There is no guarantee that this API will + * remain unchanged during the 3.3 release cycle. Please do not use this API + * without consulting with the Platform/Debug team. + * </p> + * @since 3.3 + */ +class FilterTransform { + + private Node root = new Node(); + + class Node { + private int[] filteredChildren = null; // only set for leaves + private Map children = null; // only set for parent nodes, indexed by child + + Node() { + } + + boolean addFilter(TreePath path, int childIndex, int pathIndex) { + if (pathIndex == path.getSegmentCount()) { + if (filteredChildren == null) { + filteredChildren = new int[]{childIndex}; + return true; + } + int location = Arrays.binarySearch(filteredChildren, childIndex); + if (location >= 0) { + return false; + } + location = 0 - (location + 1); + int[] next = new int[filteredChildren.length + 1]; + if (location == 0) { + next[0] = childIndex; + System.arraycopy(filteredChildren, 0, next, 1, filteredChildren.length); + } else if (location == filteredChildren.length) { + next[filteredChildren.length] = childIndex; + System.arraycopy(filteredChildren, 0, next, 0, filteredChildren.length); + } else { + System.arraycopy(filteredChildren, 0, next, 0, location); + next[location] = childIndex; + System.arraycopy(filteredChildren, location, next, location + 1, filteredChildren.length - location); + } + filteredChildren = next; + return true; + } + + if (children == null) { + children = new HashMap(); + } + Object element = path.getSegment(pathIndex); + Node node = (Node) children.get(element); + if (node == null) { + node = new Node(); + children.put(element, node); + } + return node.addFilter(path, childIndex, pathIndex + 1); + } + + boolean clear(TreePath path, int pathIndex) { + if (pathIndex == path.getSegmentCount()) { + return true; + } + if (children == null) { + return false; + } + Object child = path.getSegment(pathIndex); + Node node = (Node) children.get(child); + if (node != null) { + if (node.clear(path, pathIndex + 1)) { + children.remove(child); + } + } + return children.isEmpty(); + } + + boolean clear(TreePath path, int childIndex, int pathIndex) { + if (pathIndex == path.getSegmentCount()) { + if (filteredChildren != null) { + int location = Arrays.binarySearch(filteredChildren, childIndex); + if (location >= 0) { + // remove it + if (location == 0) { + if (filteredChildren.length == 1) { + filteredChildren = null; + return true; + } else { + int[] next = new int[filteredChildren.length - 1]; + System.arraycopy(filteredChildren, 1, next, 0, next.length); + filteredChildren = next; + } + } else if (location == (filteredChildren.length - 1)) { + int[] next = new int[filteredChildren.length - 1]; + System.arraycopy(filteredChildren, 0, next, 0, location); + filteredChildren = next; + } else { + int[] next = new int[filteredChildren.length - 1]; + System.arraycopy(filteredChildren, 0, next, 0, location); + System.arraycopy(filteredChildren, location + 1, next, location, next.length - location); + filteredChildren = next; + } + return false; + } + } else { + return false; + } + } + if (children == null) { + return false; + } + Object element = path.getSegment(pathIndex); + Node node = (Node) children.get(element); + if (node == null) { + return false; + } + boolean remove = node.clear(path, childIndex, pathIndex + 1); + if (remove) { + children.remove(element); + return filteredChildren == null && children.isEmpty(); + } else { + return false; + } + } + + Node find(TreePath path, int pathIndex) { + if (pathIndex == path.getSegmentCount()) + return this; + if (children == null) { + return null; + } + Object child = path.getSegment(pathIndex); + Node node = (Node) children.get(child); + if (node != null) { + return node.find(path, pathIndex + 1); + } + return null; + } + + int viewToModel(int childIndex) { + if (filteredChildren == null) { + return childIndex; + } + // If there are filtered children, then we want to find the + // (n+1)th missing number in the list of filtered indexes (missing + // entries are visible in the view). For example, if the request + // has asked for the model index corresponding to the 4th viewer + // index, then we want to find the 5th missing number in the + // filtered index sequence. + + int count = -1; // count from 0, 1, 2... + int missingNumbers = 0; // how many numbers missing from the filtered index + int offset = 0; // offset into the filtered index + + while (missingNumbers < (childIndex + 1)) { + count++; + if (offset < filteredChildren.length) { + if (filteredChildren[offset] == count) { + // not missing + offset++; + } else { + // missing + missingNumbers++; + } + } else { + missingNumbers++; + } + } + return count; + } + + int modelToView(int childIndex) { + if (filteredChildren == null) { + return childIndex; + } + int offset = 0; + for (int i = 0; i < filteredChildren.length; i++) { + if (childIndex == filteredChildren[i] ) { + return -1; + } else if (childIndex > filteredChildren[i]) { + offset++; + } else { + break; + } + } + return childIndex - offset; + } + + int modelToViewCount(int childCount) { + if (filteredChildren == null) { + return childCount; + } + return childCount - filteredChildren.length; + } + + boolean isFiltered(int index) { + if (filteredChildren != null) { + int location = Arrays.binarySearch(filteredChildren, index); + return location >= 0; + } + return false; + } + } + + /** + * Filters the specified child of the given parent and returns + * whether the child was already filtered. + * + * @param parentPath path to parent element + * @param childIndex index of filtered child relative to parent (in model coordinates) + * @return whether the child was already filtered + */ + public synchronized boolean addFilteredIndex(TreePath parentPath, int childIndex) { + return root.addFilter(parentPath, childIndex, 0); + } + + /** + * Clears all filtered elements. + */ + public synchronized void clear() { + root = new Node(); + } + + /** + * Clears all filters in the subtree of the given element. + * + * @param path element path + */ + public synchronized void clear(TreePath path) { + root.clear(path, 0); + } + + /** + * Clears the given filtered index of the specified parent. + * + * @param path parent path + * @param index index to clear + */ + public synchronized void clear(TreePath parentPath, int index) { + root.clear(parentPath, index, 0); + } + + /** + * Translates and returns the given model index (raw index) into + * a view index (filtered index), or -1 if filtered. + * + * @param parentPath path to parent element + * @param childIndex index of child element in model space + * @return the given index in view coordinates, or -1 if filtered. + */ + public synchronized int modelToViewIndex(TreePath parentPath, int childIndex) { + Node parentNode = root.find(parentPath, 0); + if (parentNode == null) { + return childIndex; + } + return parentNode.modelToView(childIndex); + } + + /** + * Translates and returns the given view index (filtered) into + * a model index (raw index). + * + * @param parentPath path to parent element + * @param childIndex index of child element in view space + * @return the given index in model coordinates + */ + public synchronized int viewToModelIndex(TreePath parentPath, int childIndex) { + Node parentNode = root.find(parentPath, 0); + if (parentNode == null) { + return childIndex; + } + return parentNode.viewToModel(childIndex); + } + + /** + * Returns the number of children for the given parent, in the model. + * + * @param parentPath path to parent element + * @param viewCount number of children in the view + * @return number of children in the model + */ + public synchronized int viewToModelCount(TreePath parentPath, int viewCount) { + Node parentNode = root.find(parentPath, 0); + if (parentNode != null) { + if (parentNode.filteredChildren != null) { + return viewCount + parentNode.filteredChildren.length; + } + } + return viewCount; + } + + /** + * Translates and returns the given model child count (raw) into + * a view count (filtered). + * + * @param parentPath path to parent element + * @param count child count in model space + * @return the given count in view coordinates + */ + public synchronized int modelToViewCount(TreePath parentPath, int count) { + Node parentNode = root.find(parentPath, 0); + if (parentNode == null) { + return count; + } + return parentNode.modelToViewCount(count); + } + + /** + * Returns whether the given index of the specified parent is currently filtered. + * + * @param parentPath path to parent element + * @param index index of child element + * @return whether the child is currently filtered + */ + public synchronized boolean isFiltered(TreePath parentPath, int index) { + Node parentNode = root.find(parentPath, 0); + if (parentNode == null) { + return false; + } + return parentNode.isFiltered(index); + } + + /** + * Returns filtered children of the given parent, or <code>null</code> if none. + * + * @param parentPath + * @return filtered children or <code>null</code> + */ + public int[] getFilteredChildren(TreePath parentPath) { + Node parentNode = root.find(parentPath, 0); + if (parentNode == null) { + return null; + } + return parentNode.filteredChildren; + } +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/HasChildrenUpdate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/HasChildrenUpdate.java new file mode 100644 index 000000000..3f670a0ca --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/HasChildrenUpdate.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.TreeViewer; + +/** + * @since 3.3 + */ +class HasChildrenUpdate extends ViewerUpdateMonitor implements IHasChildrenUpdate { + + /** + * Map of <code>TreePath</code>s to <code>Boolean</code>s. + */ + private Map fBooleans = new HashMap(); + + /** + * Set of <code>TreePath</code>s. + */ + private Set fElements = new HashSet(); + + private boolean fStarted = false; + private IElementContentProvider fContentProvider; + + /** + * @param contentProvider + */ + public HasChildrenUpdate(ModelContentProvider contentProvider, IElementContentProvider elementContentProvider) { + super(contentProvider); + fContentProvider = elementContentProvider; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ViewerUpdateMonitor#performUpdate() + */ + protected void performUpdate() { + Iterator iterator = fBooleans.entrySet().iterator(); + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + boolean hasChildren = ((Boolean)(entry.getValue())).booleanValue(); + TreePath elementPath = (TreePath) entry.getKey(); + ModelContentProvider contentProvider = getContentProvider(); + if (!hasChildren) { + contentProvider.clearFilters(elementPath); + } + if (ModelContentProvider.DEBUG_CONTENT_PROVIDER) { + System.out.println("setHasChildren(" + getElement(elementPath) + " >> " + hasChildren); //$NON-NLS-1$ //$NON-NLS-2$ + } + if (elementPath.getSegmentCount() > 0) { + ((TreeViewer)(contentProvider.getViewer())).setHasChildren(elementPath, hasChildren); + contentProvider.doRestore(elementPath); + } else { + ((TreeViewer)(contentProvider.getViewer())).setHasChildren(getElement(elementPath), hasChildren); + } + + } + } + + /** + * @param element + * @return + */ + protected boolean coalesce(TreePath treePath) { + fElements.add(treePath); + return true; + } + + /** + * + */ + protected void start() { + synchronized (this) { + if (fStarted) { + return; + } + fStarted = true; + } + TreeModelContentProvider contentProvider = (TreeModelContentProvider)getContentProvider(); + contentProvider.hasChildrenRequestStarted(fContentProvider); + if (!isCanceled()) { + fContentProvider.update(this); + } else { + done(); + } + } + + public TreePath[] getElements() { + return (TreePath[]) fElements.toArray(new TreePath[fElements.size()]); + } + + public void setHasChilren(TreePath element, boolean hasChildren) { + fBooleans.put(element, Boolean.valueOf(hasChildren)); + + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.ViewerUpdateMonitor#isContained(org.eclipse.jface.viewers.TreePath) + */ + boolean isContained(TreePath path) { + return ((TreePath)fElements.iterator().next()).startsWith(path, null); + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/IMementoManager.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/IMementoManager.java new file mode 100644 index 000000000..92f1d43df --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/IMementoManager.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest; + +/** + * @since 3.3 + */ +interface IMementoManager { + + /** + * Adds the request to this manager. + * + * @param memento request + */ + public void addRequest(IElementMementoRequest request); + + /** + * Notification the request is complete. + * + * @param request + */ + public void requestComplete(IElementMementoRequest request); + + /** + * Process the queued requests. Accepts no more new requests. + */ + public void processReqeusts(); +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalTreeModelViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalTreeModelViewer.java new file mode 100644 index 000000000..1e3420cae --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalTreeModelViewer.java @@ -0,0 +1,948 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicyFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.swt.widgets.Widget; +import org.eclipse.ui.IMemento; + +/** + * A tree viewer that displays a model. + * + * @since 3.3 + */ +public class InternalTreeModelViewer extends TreeViewer { + + private IPresentationContext fContext; + + /** + * Current column presentation or <code>null</code> + */ + private IColumnPresentation fColumnPresentation = null; + + /** + * Map of columns presentation id to its visible columns id's (String[]) + * When a columns presentation is not in the map, default settings are used. + */ + private Map fVisibleColumns = new HashMap(); + + /** + * Map of column id's to persisted sizes + */ + private Map fColumnSizes = new HashMap(); + + /** + * Map of column presentation id's to an array of integers representing the column order + * for that presentation, or <code>null</code> if default. + */ + private Map fColumnOrder = new HashMap(); + + /** + * Map of column presentation id to whether columns should be displayed + * for that presentation (the user can toggle columns on/off when a + * presentation is optional. + */ + private Map fShowColumns = new HashMap(); + + /** + * Item's tree path cache + */ + private static final String TREE_PATH_KEY = "TREE_PATH_KEY"; //$NON-NLS-1$ + + /** + * Memento type for column sizes. Sizes are keyed by column presentation id + */ + private static final String COLUMN_SIZES = "COLUMN_SIZES"; //$NON-NLS-1$ + /** + * Memento type for the column order for a presentation context. + * A memento is created for each column presentation + */ + private static final String COLUMN_ORDER = "COLUMN_ORDER"; //$NON-NLS-1$ + /** + * Memento type for the visible columns for a presentation context. + * A memento is created for each column presentation keyed by column number + */ + private static final String VISIBLE_COLUMNS = "VISIBLE_COLUMNS"; //$NON-NLS-1$ + /** + * Memento type for whether columns are visible for a presentation context. + * Booleans are keyed by column presentation id + */ + private static final String SHOW_COLUMNS = "SHOW_COLUMNS"; //$NON-NLS-1$ + /** + * Memento key for the number of visible columns in a VISIBLE_COLUMNS memento + * or for the width of a column + */ + private static final String SIZE = "SIZE"; //$NON-NLS-1$ + /** + * Memento key prefix a visible column + */ + private static final String COLUMN = "COLUMN"; //$NON-NLS-1$ + + /** + * True while performing an insert... we allow insert with filters + */ + private boolean fInserting = false; + + /** + * Whether to notify the content provider of an un-map operation + */ + private boolean fNotifyUnmap = true; + + /** + * Persist column sizes when they change. + * + * @since 3.2 + */ + class ColumnListener implements ControlListener { + /* (non-Javadoc) + * @see org.eclipse.swt.events.ControlListener#controlMoved(org.eclipse.swt.events.ControlEvent) + */ + public void controlMoved(ControlEvent e) { + persistColumnOrder(); + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.ControlListener#controlResized(org.eclipse.swt.events.ControlEvent) + */ + public void controlResized(ControlEvent e) { + persistColumnSizes(); + } + } + + private ColumnListener fListener = new ColumnListener(); + + /** + * Proxy to cell modifier/editor support + */ + class CellModifierProxy implements ICellModifier { + + private ICellModifier fModifier; + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object, java.lang.String) + */ + public boolean canModify(Object element, String property) { + IElementEditor editor = getElementEditorAdapter(element); + if (editor != null) { + fModifier = editor.getCellModifier(getPresentationContext(), element); + if (fModifier != null) { + if (fModifier.canModify(element, property)) { + // install cell editor + CellEditor cellEditor = editor.getCellEditor(getPresentationContext(), property, element, (Composite)getControl()); + if (cellEditor != null) { + disposeCellEditors(); + CellEditor[] newEditors = new CellEditor[getVisibleColumns().length]; + for (int i = 0; i < newEditors.length; i++) { + newEditors[i] = cellEditor; + } + setCellEditors(newEditors); + return true; + } + } + } + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object, java.lang.String) + */ + public Object getValue(Object element, String property) { + if (fModifier != null) { + return fModifier.getValue(element, property); + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object, java.lang.String, java.lang.Object) + */ + public void modify(Object element, String property, Object value) { + if (fModifier != null) { + if (element instanceof Item) { + element = ((Item)element).getData(); + } + fModifier.modify(element, property, value); + } + } + + /** + * Disposes client's column editor and cell editors + */ + protected void dispose() { + fModifier = null; + disposeCellEditors(); + setCellEditors(null); + } + + /** + * Disposes current cell editors + */ + protected void disposeCellEditors() { + CellEditor[] cellEditors = getCellEditors(); + if (cellEditors != null) { + for (int i = 0; i < cellEditors.length; i++) { + CellEditor editor = cellEditors[i]; + if (editor != null) { + editor.dispose(); + } + } + } + } + + /** + * Returns the element editor for the given element or <code>null</code>. + * + * @param input + * @return element editor or <code>null</code> + */ + protected IElementEditor getElementEditorAdapter(Object input) { + if (input instanceof IElementEditor) { + return (IElementEditor) input; + } + if (input instanceof IAdaptable) { + IAdaptable adaptable = (IAdaptable) input; + return (IElementEditor) adaptable.getAdapter(IElementEditor.class); + } + return null; + } + } + + private CellModifierProxy fCellModifier; + + /** + * @param parent + * @param style + */ + public InternalTreeModelViewer(Composite parent, int style, IPresentationContext context) { + super(parent, style); + if ((style & SWT.VIRTUAL) == 0) { + throw new IllegalArgumentException("style must include SWT.VIRTUAL"); //$NON-NLS-1$ + } + setUseHashlookup(true); + fCellModifier = new CellModifierProxy(); + fContext = context; + setContentProvider(new TreeModelContentProvider()); + setLabelProvider(new TreeModelLabelProvider(this)); + } + + /* (non-Javadoc) + * + * TODO: workaround for bug 159461 + * + * @see org.eclipse.jface.viewers.TreeViewer#hookControl(org.eclipse.swt.widgets.Control) + */ + protected void hookControl(Control control) { + Tree treeControl = (Tree) control; + treeControl.addListener(SWT.SetData, new Listener() { + public void handleEvent(Event event) { + // to avoid flash, reset previous labels/image + TreeItem item = (TreeItem) event.item; + Object[] labels = (Object[]) item.getData(LabelUpdate.PREV_LABEL_KEY); + if (labels != null) { + for (int i = 0; i < labels.length; i++) { + item.setText(i, (String)labels[i]); + } + } + Object[] images = (Object[]) item.getData(LabelUpdate.PREV_IMAGE_KEY); + if (images != null) { + for (int i = 0; i < images.length; i++) { + item.setImage(i, (Image) images[i]); + } + } + } + }); + super.hookControl(control); + } + + + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ContentViewer#handleDispose(org.eclipse.swt.events.DisposeEvent) + */ + protected void handleDispose(DisposeEvent event) { + if (fColumnPresentation != null) { + fColumnPresentation.dispose(); + } + fCellModifier.dispose(); + fContext.dispose(); + super.handleDispose(event); + } + + /** + * Returns this viewer's presentation context. + * + * @return presentation context + */ + public IPresentationContext getPresentationContext() { + return fContext; + } + + protected void unmapElement(Object element, Widget widget) { + if (fNotifyUnmap) { + // TODO: should we update the filter with the "new non-identical element"? + IContentProvider provider = getContentProvider(); + if (provider instanceof ModelContentProvider) { + ((ModelContentProvider) provider).unmapPath((TreePath) widget.getData(TREE_PATH_KEY)); + } + } + super.unmapElement(element, widget); + } + + protected void associate(Object element, Item item) { + // see AbstractTreeViewer.associate(...) + Object data = item.getData(); + if (data != null && data != element && equals(data, element)) { + // elements are equal but not identical + // -> being removed from map, but should not change filters + try { + fNotifyUnmap = false; + super.associate(element, item); + } finally { + fNotifyUnmap = true; + } + } else { + super.associate(element, item); + } + } + + /* (non-Javadoc) + * + * We need tree paths when disposed/unmapped in any order so cache the tree path. + * + * @see org.eclipse.jface.viewers.TreeViewer#mapElement(java.lang.Object, org.eclipse.swt.widgets.Widget) + */ + protected void mapElement(Object element, Widget widget) { + super.mapElement(element, widget); + if (widget instanceof Item) { + widget.setData(TREE_PATH_KEY, getTreePathFromItem((Item)widget)); + } else { + widget.setData(TREE_PATH_KEY, ModelContentProvider.EMPTY_TREE_PATH); + } + } + + /* (non-Javadoc) + * + * Override because we allow inserting with filters present. + * + * @see org.eclipse.jface.viewers.AbstractTreeViewer#insert(java.lang.Object, java.lang.Object, int) + */ + public void insert(Object parentElementOrTreePath, Object element, int position) { + try { + fInserting = true; + super.insert(parentElementOrTreePath, element, position); + } finally { + fInserting = false; + } + } + + /* (non-Javadoc) + * + * Override because we allow inserting with filters present. + * + * @see org.eclipse.jface.viewers.StructuredViewer#hasFilters() + */ + protected boolean hasFilters() { + if (fInserting) { + return false; + } + return super.hasFilters(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.AbstractTreeViewer#inputChanged(java.lang.Object, java.lang.Object) + */ + protected void inputChanged(Object input, Object oldInput) { + super.inputChanged(input, oldInput); + resetColumns(input); + } + + /** + * Configures the columns for the given viewer input. + * + * @param input + */ + protected void resetColumns(Object input) { + if (input != null) { + // only change columns if the input is non-null (persist when empty) + IColumnPresentationFactoryAdapter factory = getColumnPresenetationFactoryAdapter(input); + PresentationContext context = (PresentationContext) getPresentationContext(); + String type = null; + if (factory != null) { + type = factory.getColumnPresentationId(context, input); + } + if (type != null) { + if (fColumnPresentation != null) { + if (!fColumnPresentation.getId().equals(type)) { + // dispose old, create new + fColumnPresentation.dispose(); + fColumnPresentation = null; + } + } + if (fColumnPresentation == null) { + fColumnPresentation = factory.createColumnPresentation(context, input); + if (fColumnPresentation != null) { + fColumnPresentation.init(context); + configureColumns(); + } + } + } else { + if (fColumnPresentation != null) { + fColumnPresentation.dispose(); + fColumnPresentation = null; + configureColumns(); + } + } + } + } + + /** + * Returns the column presentation factory for the given element or <code>null</code>. + * + * @param input + * @return column presentation factory of <code>null</code> + */ + protected IColumnPresentationFactoryAdapter getColumnPresenetationFactoryAdapter(Object input) { + if (input instanceof IColumnPresentationFactoryAdapter) { + return (IColumnPresentationFactoryAdapter) input; + } + if (input instanceof IAdaptable) { + IAdaptable adaptable = (IAdaptable) input; + return (IColumnPresentationFactoryAdapter) adaptable.getAdapter(IColumnPresentationFactoryAdapter.class); + } + return null; + } + + /** + * Configures the columns based on the current settings. + * + * @param input + */ + protected void configureColumns() { + if (fColumnPresentation != null) { + IColumnPresentation build = null; + if (isShowColumns(fColumnPresentation.getId())) { + build = fColumnPresentation; + } + buildColumns(build); + } else { + // get rid of columns + buildColumns(null); + } + } + + /** + * Toggles columns on/off for the current column presentation, if any. + * + * @param show whether to show columns if the current input supports + * columns + */ + public void setShowColumns(boolean show) { + if (show) { + if (!isShowColumns()) { + fShowColumns.remove(fColumnPresentation.getId()); + } + } else { + if (isShowColumns()){ + fShowColumns.put(fColumnPresentation.getId(), Boolean.FALSE); + } + } + refreshColumns(); + } + + /** + * Resets any persisted column size for the given columns + */ + public void resetColumnSizes(String[] columnIds) { + for (int i = 0; i < columnIds.length; i++) { + fColumnSizes.remove(columnIds[i]); + } + } + + /** + * Sets the id's of visible columns, or <code>null</code> to set default columns. + * Only effects the current column presentation. + * + * @param ids visible columns + */ + public void setVisibleColumns(String[] ids) { + IColumnPresentation presentation = getColumnPresentation(); + if (presentation != null) { + fColumnOrder.remove(presentation.getId()); + fVisibleColumns.remove(presentation.getId()); + if (ids != null) { + // put back in table if not default + String[] columns = presentation.getInitialColumns(); + if (columns.length == ids.length) { + for (int i = 0; i < columns.length; i++) { + if (!ids[i].equals(columns[i])) { + fVisibleColumns.put(presentation.getId(), ids); + break; + } + } + } else { + fVisibleColumns.put(presentation.getId(), ids); + } + } + PresentationContext presentationContext = (PresentationContext) getPresentationContext(); + presentationContext.setColumns(getVisibleColumns()); + refreshColumns(); + } + } + + /** + * Refreshes the columns in the view, based on the viewer input. + */ + protected void refreshColumns() { + configureColumns(); + refresh(); + } + + /** + * Returns whether columns are being displayed currently. + * + * @return + */ + public boolean isShowColumns() { + if (fColumnPresentation != null) { + return isShowColumns(fColumnPresentation.getId()); + } + return false; + } + + /** + * Returns whether columns can be toggled on/off for the current input. + * + * @return whether columns can be toggled on/off for the current input + */ + public boolean canToggleColumns() { + return fColumnPresentation != null && fColumnPresentation.isOptional(); + } + + protected boolean isShowColumns(String columnPresentationId) { + Boolean bool = (Boolean) fShowColumns.get(columnPresentationId); + if (bool == null) { + return true; + } + return bool.booleanValue(); + } + + /** + * Creates new columns for the given presentation. + * + * TODO: does this need to be async? + * + * @param presentation + */ + protected void buildColumns(IColumnPresentation presentation) { + // dispose current columns, persisting their weights + Tree tree = getTree(); + final TreeColumn[] columns = tree.getColumns(); + String[] visibleColumnIds = getVisibleColumns(); + for (int i = 0; i < columns.length; i++) { + TreeColumn treeColumn = columns[i]; + treeColumn.removeControlListener(fListener); + treeColumn.dispose(); + } + PresentationContext presentationContext = (PresentationContext) getPresentationContext(); + if (presentation != null) { + for (int i = 0; i < visibleColumnIds.length; i++) { + String id = visibleColumnIds[i]; + String header = presentation.getHeader(id); + // TODO: allow client to specify style + TreeColumn column = new TreeColumn(tree, SWT.LEFT, i); + column.setMoveable(true); + column.setText(header); + column.setWidth(1); + ImageDescriptor image = presentation.getImageDescriptor(id); + if (image != null) { + column.setImage(((TreeModelLabelProvider)getLabelProvider()).getImage(image)); + } + column.setData(id); + } + int[] order = (int[]) fColumnOrder.get(presentation.getId()); + if (order != null) { + tree.setColumnOrder(order); + } + tree.setHeaderVisible(true); + tree.setLinesVisible(true); + presentationContext.setColumns(getVisibleColumns()); + setColumnProperties(getVisibleColumns()); + setCellModifier(fCellModifier); + } else { + tree.setHeaderVisible(false); + tree.setLinesVisible(false); + presentationContext.setColumns(null); + setCellModifier(null); + setColumnProperties(null); + } + + + int avg = tree.getSize().x; + if (visibleColumnIds != null) + avg /= visibleColumnIds.length; + + if (avg == 0) { + tree.addPaintListener(new PaintListener() { + public void paintControl(PaintEvent e) { + Tree tree2 = getTree(); + String[] visibleColumns = getVisibleColumns(); + if (visibleColumns != null) { + int avg1 = tree2.getSize().x / visibleColumns.length; + initColumns(avg1); + } + tree2.removePaintListener(this); + } + }); + } else { + initColumns(avg); + } + } + + private void initColumns(int widthHint) { + TreeColumn[] columns = getTree().getColumns(); + for (int i = 0; i < columns.length; i++) { + TreeColumn treeColumn = columns[i]; + Integer width = (Integer) fColumnSizes.get(treeColumn.getData()); + if (width == null) { + treeColumn.setWidth(widthHint); + } else { + treeColumn.setWidth(width.intValue()); + } + treeColumn.addControlListener(fListener); + } + } + + /** + * Returns the current column presentation for this viewer, or <code>null</code> + * if none. + * + * @return column presentation or <code>null</code> + */ + public IColumnPresentation getColumnPresentation() { + return fColumnPresentation; + } + + /** + * Returns identifiers of the visible columns in this viewer, or <code>null</code> + * if there is currently no column presentation. + * + * @return visible columns or <code>null</code> + */ + public String[] getVisibleColumns() { + if (isShowColumns()) { + IColumnPresentation presentation = getColumnPresentation(); + if (presentation != null) { + String[] columns = (String[]) fVisibleColumns.get(presentation.getId()); + if (columns == null) { + return presentation.getInitialColumns(); + } + return columns; + } + } + return null; + } + + /** + * Persists column sizes in cache + */ + protected void persistColumnSizes() { + Tree tree = getTree(); + TreeColumn[] columns = tree.getColumns(); + for (int i = 0; i < columns.length; i++) { + TreeColumn treeColumn = columns[i]; + Object id = treeColumn.getData(); + fColumnSizes.put(id, new Integer(treeColumn.getWidth())); + } + } + + /** + * Persists column ordering + */ + protected void persistColumnOrder() { + IColumnPresentation presentation = getColumnPresentation(); + if (presentation != null) { + Tree tree = getTree(); + int[] order = tree.getColumnOrder(); + if (order.length > 0) { + for (int i = 0; i < order.length; i++) { + if (i != order[i]) { + // non default order + fColumnOrder.put(presentation.getId(), order); + return; + } + } + } + // default order + fColumnOrder.remove(presentation.getId()); + } + } + + /** + * Save viewer state into the given memento. + * + * @param memento + */ + public void saveState(IMemento memento) { + if (!fColumnSizes.isEmpty()) { + Iterator iterator = fColumnSizes.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Entry) iterator.next(); + IMemento sizes = memento.createChild(COLUMN_SIZES, (String)entry.getKey()); + sizes.putInteger(SIZE, ((Integer)entry.getValue()).intValue()); + } + } + if (!fShowColumns.isEmpty()) { + Iterator iterator = fShowColumns.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Entry) iterator.next(); + IMemento sizes = memento.createChild(SHOW_COLUMNS, (String)entry.getKey()); + sizes.putString(SHOW_COLUMNS, ((Boolean)entry.getValue()).toString()); + } + } + if (!fVisibleColumns.isEmpty()) { + Iterator iterator = fVisibleColumns.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Entry) iterator.next(); + String id = (String) entry.getKey(); + IMemento visible = memento.createChild(VISIBLE_COLUMNS, id); + String[] columns = (String[]) entry.getValue(); + visible.putInteger(SIZE, columns.length); + for (int i = 0; i < columns.length; i++) { + visible.putString(COLUMN+Integer.toString(i), columns[i]); + } + } + } + if (!fColumnOrder.isEmpty()) { + Iterator iterator = fColumnOrder.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Entry) iterator.next(); + String id = (String) entry.getKey(); + IMemento orderMemento = memento.createChild(COLUMN_ORDER, id); + int[] order = (int[]) entry.getValue(); + orderMemento.putInteger(SIZE, order.length); + for (int i = 0; i < order.length; i++) { + orderMemento.putInteger(COLUMN+Integer.toString(i), order[i]); + } + } + } + } + + /** + * Initializes viewer state from the memento + * + * @param memento + */ + public void initState(IMemento memento) { + IMemento[] mementos = memento.getChildren(COLUMN_SIZES); + for (int i = 0; i < mementos.length; i++) { + IMemento child = mementos[i]; + String id = child.getID(); + Integer size = child.getInteger(SIZE); + if (size != null) { + fColumnSizes.put(id, size); + } + } + mementos = memento.getChildren(SHOW_COLUMNS); + for (int i = 0; i < mementos.length; i++) { + IMemento child = mementos[i]; + String id = child.getID(); + Boolean bool = Boolean.valueOf(child.getString(SHOW_COLUMNS)); + if (!bool.booleanValue()) { + fShowColumns.put(id, bool); + } + } + mementos = memento.getChildren(VISIBLE_COLUMNS); + for (int i = 0; i < mementos.length; i++) { + IMemento child = mementos[i]; + String id = child.getID(); + Integer integer = child.getInteger(SIZE); + if (integer != null) { + int length = integer.intValue(); + String[] columns = new String[length]; + for (int j = 0; j < length; j++) { + columns[j] = child.getString(COLUMN+Integer.toString(j)); + } + fVisibleColumns.put(id, columns); + } + } + mementos = memento.getChildren(COLUMN_ORDER); + for (int i = 0; i < mementos.length; i++) { + IMemento child = mementos[i]; + String id = child.getID(); + Integer integer = child.getInteger(SIZE); + if (integer != null) { + int length = integer.intValue(); + int[] order = new int[length]; + for (int j = 0; j < length; j++) { + order[j] = child.getInteger(COLUMN+Integer.toString(j)).intValue(); + } + fColumnOrder.put(id, order); + } + } + } + + /** + * Returns whether the candidate selection should override the current + * selection. + * + * @param current + * @param curr + * @return + */ + protected boolean overrideSelection(ISelection current, ISelection candidate) { + IModelSelectionPolicy selectionPolicy = getSelectionPolicy(current); + if (selectionPolicy == null) { + return true; + } + if (selectionPolicy.contains(candidate, getPresentationContext())) { + return selectionPolicy.overrides(current, candidate, getPresentationContext()); + } + return !selectionPolicy.isSticky(current, getPresentationContext()); + } + + /** + * Returns the selection policy associated with the given selection + * or <code>null</code> if none. + * + * @param selection or <code>null</code> + * @return selection policy or <code>null</code> + */ + protected IModelSelectionPolicy getSelectionPolicy(ISelection selection) { + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + Object element = ss.getFirstElement(); + if (element instanceof IAdaptable) { + IAdaptable adaptable = (IAdaptable) element; + IModelSelectionPolicyFactoryAdapter factory = (IModelSelectionPolicyFactoryAdapter) adaptable.getAdapter(IModelSelectionPolicyFactoryAdapter.class); + if (factory != null) { + return factory.createModelSelectionPolicyAdapter(adaptable, getPresentationContext()); + } + } + } + return null; + } + + /* (non-Javadoc) + * + * Consider selection policy + * + * @see org.eclipse.jface.viewers.StructuredViewer#setSelection(org.eclipse.jface.viewers.ISelection, boolean) + */ + public void setSelection(ISelection selection, boolean reveal) { + if (!overrideSelection(getSelection(), selection)) { + return; + } + super.setSelection(selection, reveal); + } + + /** + * Registers the specified listener for view update notifications. + * + * @param listener listener + */ + public void addViewerUpdateListener(IViewerUpdateListener listener) { + ((ModelContentProvider)getContentProvider()).addViewerUpdateListener(listener); + } + + /** + * Removes the specified listener from update notifications. + * + * @param listener listener + */ + public void removeViewerUpdateListener(IViewerUpdateListener listener) { + ModelContentProvider cp = (ModelContentProvider)getContentProvider(); + if (cp != null) { + cp.removeViewerUpdateListener(listener); + } + } + + /** + * Registers the given listener for model delta notification. + * + * @param listener model delta listener + */ + public void addModelChangedListener(IModelChangedListener listener) { + ((ModelContentProvider)getContentProvider()).addModelChangedListener(listener); + } + + /** + * Unregisters the given listener from model delta notification. + * + * @param listener model delta listener + */ + public void removeModelChangedListener(IModelChangedListener listener) { + ModelContentProvider cp = (ModelContentProvider)getContentProvider(); + if (cp != null) { + cp.removeModelChangedListener(listener); + } + } + + /* + * (non-Javadoc) Method declared in AbstractTreeViewer. + */ + protected void doUpdateItem(final Item item, Object element) { + if (!(item instanceof TreeItem)) { + return; + } + TreeItem treeItem = (TreeItem) item; + if (treeItem.isDisposed()) { + unmapElement(element, treeItem); + return; + } + + ((TreeModelLabelProvider)getLabelProvider()).update(element, getViewerRowFromItem(treeItem)); + + // As it is possible for user code to run the event + // loop check here. + if (item.isDisposed()) { + unmapElement(element, item); + } + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/LabelUpdate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/LabelUpdate.java new file mode 100644 index 000000000..25d1b48d9 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/LabelUpdate.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model; + +import org.eclipse.debug.internal.ui.commands.actions.AbstractRequestMonitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.TreeItem; + +/** + * @since 3.3 + */ +class LabelUpdate extends AbstractRequestMonitor implements ILabelUpdate { + + private Object fElement; + private String[] fColumnIds; + private RGB[] fBackgrounds; + private RGB[] fForegrounds; + private ImageDescriptor[] fImageDescriptors; + private String[] fLabels; + private FontData[] fFontDatas; + private TreeModelLabelProvider fProvider; + private TreeItem fItem; + private int fNumColumns; + + /** + * Label/Image cache keys + * TODO: workaround for bug 159461 + */ + static String PREV_LABEL_KEY = "PREV_LABEL_KEY"; //$NON-NLS-1$ + static String PREV_IMAGE_KEY = "PREV_IMAGE_KEY"; //$NON-NLS-1$ + + /** + * @param element element the label is for + * @param provider label provider to callback to + * @param columnId column identifier or <code>null</code> + */ + public LabelUpdate(Object element, TreeItem item, TreeModelLabelProvider provider, String[] columnIds) { + fElement = element; + fProvider = provider; + fColumnIds = columnIds; + fItem = item; + fNumColumns = 1; + if (columnIds != null) { + fNumColumns = columnIds.length; + } + fLabels = new String[fNumColumns]; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate#getColumnIds() + */ + public String[] getColumnIds() { + return fColumnIds; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate#getElement() + */ + public Object getElement() { + return fElement; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate#setBackground(org.eclipse.swt.graphics.RGB, int) + */ + public void setBackground(RGB background, int columnIndex) { + if (background == null) { + return; + } + if (fBackgrounds == null) { + fBackgrounds = new RGB[fNumColumns]; + } + fBackgrounds[columnIndex] = background; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate#setFontData(org.eclipse.swt.graphics.FontData, int) + */ + public void setFontData(FontData fontData, int columnIndex) { + if (fontData == null) { + return; + } + if (fFontDatas == null) { + fFontDatas = new FontData[fNumColumns]; + } + fFontDatas[columnIndex] = fontData; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate#setForeground(org.eclipse.swt.graphics.RGB, int) + */ + public void setForeground(RGB foreground, int columnIndex) { + if (foreground == null) { + return; + } + if (fForegrounds == null) { + fForegrounds = new RGB[fNumColumns]; + } + fForegrounds[columnIndex] = foreground; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate#setImageDescriptor(org.eclipse.jface.resource.ImageDescriptor, int) + */ + public void setImageDescriptor(ImageDescriptor image, int columnIndex) { + if (image == null) { + return; + } + if (fImageDescriptors == null) { + fImageDescriptors = new ImageDescriptor[fNumColumns]; + } + fImageDescriptors[columnIndex] = image; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate#setLabel(java.lang.String, int) + */ + public void setLabel(String text, int columnIndex) { + fLabels[columnIndex] = text; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate#getPresentationContext() + */ + public IPresentationContext getPresentationContext() { + return fProvider.getPresentationContext(); + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IProgressMonitor#done() + */ + public void done() { + fProvider.complete(this); + } + + /** + * Applies settings to viewer cell + */ + public void update() { + if (!fItem.isDisposed()) { + if (fColumnIds == null) { + fItem.setText(fLabels[0]); + } else { + fItem.setText(fLabels); + } + fItem.setData(PREV_LABEL_KEY, fLabels); + if (fImageDescriptors == null) { + fItem.setImage((Image)null); + fItem.setData(PREV_IMAGE_KEY, null); // TODO: bug 159461 + } else { + if (fImageDescriptors == null) { + fItem.setImage((Image)null); + fItem.setData(PREV_IMAGE_KEY, null); + } else { + Image[] images = new Image[fImageDescriptors.length]; + for (int i = 0; i < fImageDescriptors.length; i++) { + images[i] = fProvider.getImage(fImageDescriptors[i]); + } + if (fColumnIds == null) { + fItem.setImage(images[0]); + } else { + fItem.setImage(images); + } + fItem.setData(PREV_IMAGE_KEY, images); // TODO: bug 159461 + } + } + if (fForegrounds == null) { + fItem.setForeground((Color)null); + } else { + if (fColumnIds == null) { + fItem.setForeground(fProvider.getColor(fForegrounds[0])); + } else { + for (int i = 0; i< fForegrounds.length; i++) { + fItem.setForeground(i, fProvider.getColor(fForegrounds[i])); + } + } + } + if (fBackgrounds == null) { + fItem.setBackground((Color)null); + } else { + if (fColumnIds == null) { + fItem.setBackground(fProvider.getColor(fBackgrounds[0])); + } else { + for (int i = 0; i< fBackgrounds.length; i++) { + fItem.setBackground(i, fProvider.getColor(fBackgrounds[i])); + } + } + } + if (fFontDatas == null) { + fItem.setFont((Font)null); + } else { + if (fColumnIds == null) { + fItem.setFont(fProvider.getFont(fFontDatas[0])); + } else { + for (int i = 0; i < fFontDatas.length; i++) { + fItem.setFont(i, fProvider.getFont(fFontDatas[i])); + } + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate#getElement(org.eclipse.jface.viewers.TreePath) + */ + public Object getElement(TreePath path) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/MementoUpdate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/MementoUpdate.java new file mode 100644 index 000000000..d9b29d8a9 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/MementoUpdate.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model; + +import org.eclipse.debug.internal.ui.commands.actions.AbstractRequestMonitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.ui.IMemento; + +/** + * @since 3.3 + */ +abstract class MementoUpdate extends AbstractRequestMonitor implements IViewerUpdate { + + private IPresentationContext fContext; + private Object fElement; + private IMemento fMemento; + protected ModelContentProvider fProvider; + + /** + * Constructs a viewer state request. + * + * @param viewer viewer + * @param element element + * @param memento memento + */ + public MementoUpdate(ModelContentProvider provider, IPresentationContext context, Object element, IMemento memento) { + fContext = context; + fElement = element; + fMemento = memento; + fProvider = provider; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate#getPresentationContext() + */ + public IPresentationContext getPresentationContext() { + return fContext; + } + + public Object getElement() { + return fElement; + } + + public IMemento getMemento() { + return fMemento; + } + + public ModelContentProvider getContentProvider() { + return fProvider; + } + + public Object getElement(TreePath path) { + return fProvider.getElement(path); + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ModelContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ModelContentProvider.java new file mode 100644 index 000000000..8718f27a0 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ModelContentProvider.java @@ -0,0 +1,903 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDeltaVisitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.debug.ui.commands.IStatusMonitor; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.XMLMemento; +import org.eclipse.ui.progress.UIJob; +import org.eclipse.ui.progress.WorkbenchJob; + +/** + * Content provider for a virtual viewer. + * + * @since 3.3 + */ +abstract class ModelContentProvider implements IContentProvider, IModelChangedListener { + + private Viewer fViewer; + + private Map fModelProxies = new HashMap(); // model proxy by element + + /** + * Map of nodes that have been filtered from the viewer. + */ + private FilterTransform fTransform = new FilterTransform(); + + /** + * Model listeners + */ + private ListenerList fModelListeners = new ListenerList(); + + /** + * Update listeners + */ + private ListenerList fUpdateListeners = new ListenerList(); + + /** + * List of updates in progress + */ + private List fUpdatesInProgress = new ArrayList(); + + /** + * Map of viewer states keyed by viewer input mementos + */ + private Map fViewerStates = new LRUMap(20); + + /** + * Pending viewer state to be restored + */ + private ModelDelta fPendingState = null; + + /** + * Used to determine when restoration delta has been processed + */ + class CheckState implements IModelDeltaVisitor { + private boolean complete = true; + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelDeltaVisitor#visit(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta, int) + */ + public boolean visit(IModelDelta delta, int depth) { + if (delta.getFlags() != IModelDelta.NO_CHANGE) { + complete = false; + return false; + } + return true; + } + + public boolean isComplete() { + return complete; + } + } + + /** + * LRU cache for viewer states + */ + class LRUMap extends LinkedHashMap { + private static final long serialVersionUID= 1L; + private int fMaxSize; + LRUMap(int maxSize) { + super(); + fMaxSize = maxSize; + } + protected boolean removeEldestEntry(Entry eldest) { + return size() > fMaxSize; + } + } + + /** + * Update type constants + */ + private static final int UPDATE_SEQUENCE_BEGINS = 0; + private static final int UPDATE_SEQUENCE_COMPLETE = 1; + private static final int UPDATE_BEGINS = 2; + private static final int UPDATE_COMPLETE = 3; + + /** + * Constant for an empty tree path. + */ + protected static final TreePath EMPTY_TREE_PATH = new TreePath(new Object[]{}); + + // debug flag + public static boolean DEBUG_CONTENT_PROVIDER = false; + + static { + DEBUG_CONTENT_PROVIDER = DebugUIPlugin.DEBUG && "true".equals( //$NON-NLS-1$ + Platform.getDebugOption("org.eclipse.debug.ui/debug/viewers/contentProvider")); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public synchronized void dispose() { + fModelListeners.clear(); + fUpdateListeners.clear(); + disposeAllModelProxies(); + fViewer = null; + } + + public synchronized boolean isDisposed() { + return fViewer == null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, + * java.lang.Object, java.lang.Object) + */ + public synchronized void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + fViewer = viewer; + if (oldInput != null) { + saveViewerState(oldInput); + } + if (newInput != oldInput) { + disposeAllModelProxies(); + fTransform.clear(); + if (newInput != null) { + installModelProxy(newInput); + restoreViewerState(newInput); + } + } + } + + /** + * Restores viewer state for the new input + * + * @param newInput + */ + protected void restoreViewerState(final Object input) { + fPendingState = null; + final IElementMementoProvider stateProvider = getViewerStateAdapter(input); + if (stateProvider != null) { + // build a model delta representing expansion and selection state + final ModelDelta delta = new ModelDelta(input, IModelDelta.NO_CHANGE); + final XMLMemento inputMemento = XMLMemento.createWriteRoot("VIEWER_INPUT_MEMENTO"); //$NON-NLS-1$ + final IMementoManager manager = new IMementoManager() { + + private IElementMementoRequest fRequest; + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IMementoManager#requestComplete(org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest) + */ + public synchronized void requestComplete(IElementMementoRequest request) { + if (!request.isCanceled() && (request.getStatus() == null || request.getStatus().isOK())) { + XMLMemento keyMemento = (XMLMemento) delta.getElement(); + StringWriter writer = new StringWriter(); + try { + keyMemento.save(writer); + final ModelDelta stateDelta = (ModelDelta) fViewerStates.remove(writer.toString()); + if (stateDelta != null) { + if (DEBUG_CONTENT_PROVIDER) { + System.out.println("RESTORE: " + stateDelta.toString()); //$NON-NLS-1$ + } + stateDelta.setElement(input); + // begin restoration + UIJob job = new UIJob("restore state") { //$NON-NLS-1$ + public IStatus runInUIThread(IProgressMonitor monitor) { + if (input.equals(getViewer().getInput())) { + fPendingState = stateDelta; + doInitialRestore(); + } + return Status.OK_STATUS; + } + + }; + job.setSystem(true); + job.schedule(); + } + } catch (IOException e) { + // TODO log + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IMementoManager#processReqeusts() + */ + public void processReqeusts() { + stateProvider.encodeElement(fRequest); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IMementoManager#addRequest(org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest) + */ + public synchronized void addRequest(IElementMementoRequest req) { + fRequest = req; + } + + }; + manager.addRequest(new ElementMementoRequest(ModelContentProvider.this, manager, getPresentationContext(), + delta.getElement(), inputMemento, delta)); + manager.processReqeusts(); + } + } + + /** + * Restore selection/expansion based on items already in the viewer + */ + abstract protected void doInitialRestore(); + + /** + * @param delta + */ + abstract void doRestore(final ModelDelta delta); + + /** + * Perform any restoration required for the given tree path. + * + * @param path + */ + protected void doRestore(final TreePath path) { + if (fPendingState == null) { + return; + } + IModelDeltaVisitor visitor = new IModelDeltaVisitor() { + public boolean visit(IModelDelta delta, int depth) { + if (delta.getParentDelta() == null) { + return true; + } + Object element = delta.getElement(); + Object potentialMatch = path.getSegment(depth - 1); + if (element instanceof IMemento) { + IElementMementoProvider provider = getViewerStateAdapter(getViewer().getInput()); + if (provider != null) { + provider.compareElement( + new ElementCompareRequest(ModelContentProvider.this, + potentialMatch, (IMemento) element, (ModelDelta)delta)); + } + } else { + if (element.equals(potentialMatch)) { + // already processed - visit children + return path.getSegmentCount() > depth; + } + } + return false; + } + }; + fPendingState.accept(visitor); + } + + /** + * Saves the viewer's state for the previous input. + * + * @param oldInput + */ + protected void saveViewerState(Object input) { + IElementMementoProvider stateProvider = getViewerStateAdapter(input); + if (stateProvider != null) { + // build a model delta representing expansion and selection state + ModelDelta delta = new ModelDelta(input, IModelDelta.NO_CHANGE); + buildViewerState(delta); + if (delta.getChildDeltas().length > 0) { + // encode delta with mementos in place of elements, in non-UI thread + encodeDelta(delta, stateProvider); + } + } + } + + /** + * Encodes delta elements into mementos using the given provider. + * + * @param delta + * @param stateProvider + */ + protected void encodeDelta(final ModelDelta rootDelta, final IElementMementoProvider stateProvider) { + final XMLMemento inputMemento = XMLMemento.createWriteRoot("VIEWER_INPUT_MEMENTO"); //$NON-NLS-1$ + final XMLMemento childrenMemento = XMLMemento.createWriteRoot("CHILDREN_MEMENTO"); //$NON-NLS-1$ + final IMementoManager manager = new IMementoManager() { + + private Set requests = new HashSet(); + private boolean abort = false; + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IMementoManager#requestComplete(org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest) + */ + public synchronized void requestComplete(IElementMementoRequest request) { + if (!abort) { + if (!request.isCanceled() && (request.getStatus() == null || request.getStatus().isOK())) { + requests.remove(request); + if (requests.isEmpty()) { + XMLMemento keyMemento = (XMLMemento) rootDelta.getElement(); + StringWriter writer = new StringWriter(); + try { + keyMemento.save(writer); + fViewerStates.put(writer.toString(), rootDelta); + } catch (IOException e) { + // TODO log + } + } + } else { + abort = true; + Iterator iterator = requests.iterator(); + while (iterator.hasNext()) { + IElementMementoRequest req = (IElementMementoRequest) iterator.next(); + req.setCanceled(true); + } + requests.clear(); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IMementoManager#processReqeusts() + */ + public void processReqeusts() { + IElementMementoRequest[] req = (IElementMementoRequest[]) requests.toArray(new IElementMementoRequest[requests.size()]); + for (int i = 0; i < req.length; i++) { + stateProvider.encodeElement(req[i]); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IMementoManager#addRequest(org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest) + */ + public synchronized void addRequest(IElementMementoRequest request) { + requests.add(request); + } + + }; + IModelDeltaVisitor visitor = new IModelDeltaVisitor() { + public boolean visit(IModelDelta delta, int depth) { + if (delta.getParentDelta() == null) { + manager.addRequest( + new ElementMementoRequest(ModelContentProvider.this, manager, getPresentationContext(), + delta.getElement(), inputMemento, (ModelDelta)delta)); + } else { + manager.addRequest( + new ElementMementoRequest(ModelContentProvider.this, manager, getPresentationContext(), + delta.getElement(), childrenMemento.createChild("CHILD_ELEMENT"), (ModelDelta)delta)); //$NON-NLS-1$ + } + return true; + } + }; + rootDelta.accept(visitor); + manager.processReqeusts(); + } + + /** + * Builds a delta with the given root delta for expansion/selection state. + * + * @param delta root delta + */ + protected abstract void buildViewerState(ModelDelta delta); + + /** + * Uninstalls the model proxy installed for the given element, if any. + * + * @param element + */ + protected synchronized void disposeModelProxy(Object element) { + IModelProxy proxy = (IModelProxy) fModelProxies.remove(element); + if (proxy != null) { + proxy.dispose(); + } + } + + /** + * Uninstalls each model proxy + */ + protected synchronized void disposeAllModelProxies() { + Iterator updatePolicies = fModelProxies.values().iterator(); + while (updatePolicies.hasNext()) { + IModelProxy proxy = (IModelProxy) updatePolicies.next(); + proxy.dispose(); + } + fModelProxies.clear(); + } + + /** + * Installs the model proxy for the given element into this content provider + * if not already installed. + * + * @param element + * element to install an update policy for + */ + protected synchronized void installModelProxy(Object element) { + if (!fModelProxies.containsKey(element)) { + IModelProxyFactoryAdapter modelProxyFactory = getModelProxyFactoryAdapter(element); + if (modelProxyFactory != null) { + final IModelProxy proxy = modelProxyFactory.createModelProxy( + element, getPresentationContext()); + if (proxy != null) { + fModelProxies.put(element, proxy); + Job job = new Job("Model Proxy installed notification job") {//$NON-NLS-1$ + protected IStatus run(IProgressMonitor monitor) { + if (!monitor.isCanceled()) { + proxy.init(getPresentationContext()); + Object[] mcls = fModelListeners.getListeners(); + for (int i = 0; i < mcls.length; i++) { + proxy.addModelChangedListener((IModelChangedListener) mcls[i]); + } + proxy + .addModelChangedListener(ModelContentProvider.this); + proxy.installed(getViewer()); + } + return Status.OK_STATUS; + } + }; + job.setSystem(true); + job.schedule(); + } + } + } + } + + /** + * Returns the model proxy factory for the given element or + * <code>null</code> if none. + * + * @param element + * element to retrieve adapter for + * @return model proxy factory adapter or <code>null</code> + */ + protected IModelProxyFactoryAdapter getModelProxyFactoryAdapter(Object element) { + IModelProxyFactoryAdapter adapter = null; + if (element instanceof IModelProxyFactoryAdapter) { + adapter = (IModelProxyFactoryAdapter) element; + } else if (element instanceof IAdaptable) { + IAdaptable adaptable = (IAdaptable) element; + adapter = (IModelProxyFactoryAdapter) adaptable.getAdapter(IModelProxyFactoryAdapter.class); + } + return adapter; + } + + /** + * Returns the viewer state adapter for the given element or + * <code>null</code> if none. + * + * @param element + * element to retrieve adapter for + * @return viewer state adapter or <code>null</code> + */ + protected IElementMementoProvider getViewerStateAdapter(Object element) { + IElementMementoProvider adapter = null; + if (element instanceof IElementMementoProvider) { + adapter = (IElementMementoProvider) element; + } else if (element instanceof IAdaptable) { + IAdaptable adaptable = (IAdaptable) element; + adapter = (IElementMementoProvider) adaptable.getAdapter(IElementMementoProvider.class); + } + return adapter; + } + + /** + * Returns the presentation context for this content provider. + * + * @return presentation context + */ + protected abstract IPresentationContext getPresentationContext(); + + /* + * (non-Javadoc) + * + * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener#modelChanged(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta) + */ + public void modelChanged(final IModelDelta delta, final IModelProxy proxy) { + WorkbenchJob job = new WorkbenchJob("process model delta") { //$NON-NLS-1$ + public IStatus runInUIThread(IProgressMonitor monitor) { + if (!proxy.isDisposed()) { + updateNodes(new IModelDelta[] { delta }); + } + return Status.OK_STATUS; + } + }; + job.setSystem(true); + job.schedule(); + + } + + protected void updateNodes(IModelDelta[] nodes) { + for (int i = 0; i < nodes.length; i++) { + IModelDelta node = nodes[i]; + int flags = node.getFlags(); + + if ((flags & IModelDelta.ADDED) != 0) { + handleAdd(node); + } + if ((flags & IModelDelta.REMOVED) != 0) { + handleRemove(node); + } + if ((flags & IModelDelta.CONTENT) != 0) { + handleContent(node); + } + if ((flags & IModelDelta.EXPAND) != 0) { + handleExpand(node); + } + if ((flags & IModelDelta.SELECT) != 0) { + handleSelect(node); + } + if ((flags & IModelDelta.STATE) != 0) { + handleState(node); + } + if ((flags & IModelDelta.INSERTED) != 0) { + handleInsert(node); + } + if ((flags & IModelDelta.REPLACED) != 0) { + handleReplace(node); + } + if ((flags & IModelDelta.INSTALL) != 0) { + handleInstall(node); + } + if ((flags & IModelDelta.UNINSTALL) != 0) { + handleUninstall(node); + } + updateNodes(node.getChildDeltas()); + } + } + + /** + * Returns the content adapter for the given element or + * <code>null</code> if none. + * + * @param element + * element to retrieve adapter for + * @return content adapter or <code>null</code> + */ + protected IElementContentProvider getContentAdapter(Object element) { + IElementContentProvider adapter = null; + if (element instanceof IElementContentProvider) { + adapter = (IElementContentProvider) element; + } else if (element instanceof IAdaptable) { + IAdaptable adaptable = (IAdaptable) element; + adapter = (IElementContentProvider) adaptable.getAdapter(IElementContentProvider.class); + } + return adapter; + } + + protected abstract void handleState(IModelDelta delta); + + protected abstract void handleSelect(IModelDelta delta); + + protected abstract void handleExpand(IModelDelta delta); + + protected abstract void handleContent(IModelDelta delta); + + protected abstract void handleRemove(IModelDelta delta); + + protected abstract void handleAdd(IModelDelta delta); + + protected abstract void handleInsert(IModelDelta delta); + + protected abstract void handleReplace(IModelDelta delta); + + protected void handleInstall(IModelDelta delta) { + installModelProxy(delta.getElement()); + } + + protected void handleUninstall(IModelDelta delta) { + disposeModelProxy(delta.getElement()); + } + + /** + * Returns a tree path for the node, *not* including the root element. + * + * @param node + * model delta + * @return corresponding tree path + */ + protected TreePath getViewerTreePath(IModelDelta node) { + ArrayList list = new ArrayList(); + IModelDelta parentDelta = node.getParentDelta(); + while (parentDelta != null) { + list.add(0, node.getElement()); + node = parentDelta; + parentDelta = node.getParentDelta(); + } + return new TreePath(list.toArray()); + } + + /** + * Returns the viewer this content provider is working for. + * + * @return viewer + */ + protected Viewer getViewer() { + return fViewer; + } + + /** + * Translates and returns the given child index from the viewer coordinate + * space to the model coordinate space. + * + * @param parentPath path to parent element + * @param index index of child element in viewer (filtered) space + * @return index of child element in model (raw) space + */ + public /* protected */ int viewToModelIndex(TreePath parentPath, int index) { + return fTransform.viewToModelIndex(parentPath, index); + } + + /** + * Translates and returns the given child count from the viewer coordinate + * space to the model coordinate space. + * + * @param parentPath path to parent element + * @param count number of child elements in viewer (filtered) space + * @return number of child elements in model (raw) space + */ + public /* protected */ int viewToModelCount(TreePath parentPath, int count) { + return fTransform.viewToModelCount(parentPath, count); + } + + /** + * Translates and returns the given child index from the model coordinate + * space to the viewer coordinate space. + * + * @param parentPath path to parent element + * @param index index of child element in model (raw) space + * @return index of child element in viewer (filtered) space + */ + protected int modelToViewIndex(TreePath parentPath, int index) { + return fTransform.modelToViewIndex(parentPath, index); + } + + /** + * Translates and returns the given child count from the model coordinate + * space to the viewer coordinate space. + * + * @param parentPath path to parent element + * @param count child count element in model (raw) space + * @return child count in viewer (filtered) space + */ + protected int modelToViewChildCount(TreePath parentPath, int count) { + return fTransform.modelToViewCount(parentPath, count); + } + + /** + * Notes that the child at the specified index of the given parent element + * has been filtered from the viewer. Returns whether the child at the given + * index was already filtered. + * + * @param parentPath path to parent element + * @param index index of child element to be filtered + * @return whether the child was already filtered + */ + protected boolean addFilteredIndex(TreePath parentPath, int index) { + return fTransform.addFilteredIndex(parentPath, index); + } + + /** + * Returns whether the given element is filtered. + * + * @param parentElementOrTreePath + * the parent element or path + * @param element + * the child element + * @return whether to filter the element + */ + protected boolean shouldFilter(Object parentElementOrTreePath, Object element) { + ViewerFilter[] filters = ((StructuredViewer)fViewer).getFilters(); + if (filters.length > 0) { + for (int j = 0; j < filters.length; j++) { + if (!(filters[j].select(fViewer, parentElementOrTreePath, element))) { + return true; + } + } + } + return false; + } + + /** + * Returns whether the given index of the specified parent was previously filtered. + * + * @param parentPath + * @param index + * @return whether the element at the given index was filtered + */ + protected boolean isFiltered(TreePath parentPath, int index) { + return fTransform.isFiltered(parentPath, index); + } + + /** + * Notification the given element is being unmapped. + * + * @param path + */ + protected void unmapPath(TreePath path) { + //System.out.println("Unmap " + path.getLastSegment()); + fTransform.clear(path); + } + + /** + * Returns filtered children or <code>null</code> + * @param parent + * @return filtered children or <code>null</code> + */ + protected int[] getFilteredChildren(TreePath parent) { + return fTransform.getFilteredChildren(parent); + } + + protected void clearFilteredChild(TreePath parent, int modelIndex) { + fTransform.clear(parent, modelIndex); + } + + protected void clearFilters(TreePath parent) { + fTransform.clear(parent); + } + + + + protected void checkIfRestoreComplete() { + CheckState state = new CheckState(); + fPendingState.accept(state); + if (state.isComplete()) { + fPendingState = null; + if (DEBUG_CONTENT_PROVIDER) { + System.out.println("RESTORE COMPELTE"); //$NON-NLS-1$ + } + } + } + + void addViewerUpdateListener(IViewerUpdateListener listener) { + fUpdateListeners.add(listener); + } + + void removeViewerUpdateListener(IViewerUpdateListener listener) { + fUpdateListeners.remove(listener); + } + + /** + * Notification an update request has started + * + * @param update + */ + void updateStarted(IStatusMonitor update) { + boolean begin = false; + synchronized (fUpdatesInProgress) { + begin = fUpdatesInProgress.isEmpty(); + fUpdatesInProgress.add(update); + } + if (begin) { + notifyUpdate(UPDATE_SEQUENCE_BEGINS, null); + } + notifyUpdate(UPDATE_BEGINS, update); + } + + /** + * Notification an update request has completed + * + * @param update + */ + void updateComplete(IStatusMonitor update) { + boolean end = false; + synchronized (fUpdatesInProgress) { + fUpdatesInProgress.remove(update); + end = fUpdatesInProgress.isEmpty(); + } + notifyUpdate(UPDATE_COMPLETE, update); + if (end) { + notifyUpdate(UPDATE_SEQUENCE_COMPLETE, null); + } + } + + protected void notifyUpdate(final int type, final IStatusMonitor update) { + if (!fUpdateListeners.isEmpty()) { + Object[] listeners = fUpdateListeners.getListeners(); + for (int i = 0; i < listeners.length; i++) { + final IViewerUpdateListener listener = (IViewerUpdateListener) listeners[i]; + SafeRunner.run(new ISafeRunnable() { + public void run() throws Exception { + switch (type) { + case UPDATE_SEQUENCE_BEGINS: + listener.viewerUpdatesBegin(); + break; + case UPDATE_SEQUENCE_COMPLETE: + listener.viewerUpdatesComplete(); + break; + case UPDATE_BEGINS: + listener.updateStarted(update); + break; + case UPDATE_COMPLETE: + listener.updateComplete(update); + break; + } + } + public void handleException(Throwable exception) { + DebugUIPlugin.log(exception); + } + }); + } + } + } + + protected void cancelSubtreeUpdates(TreePath path) { + synchronized (fUpdatesInProgress) { + for (int i = 0; i < fUpdatesInProgress.size(); i++) { + ViewerUpdateMonitor update = (ViewerUpdateMonitor) fUpdatesInProgress.get(i); + if (update.isContained(path)) { + update.setCanceled(true); + } + } + } + } + + /** + * Registers the given listener for model delta notification. + * + * @param listener model delta listener + */ + void addModelChangedListener(IModelChangedListener listener) { + fModelListeners.add(listener); + Iterator proxies = fModelProxies.values().iterator(); + while (proxies.hasNext()) { + IModelProxy proxy = (IModelProxy) proxies.next(); + proxy.addModelChangedListener(listener); + } + } + + /** + * Unregisters the given listener from model delta notification. + * + * @param listener model delta listener + */ + void removeModelChangedListener(IModelChangedListener listener) { + fModelListeners.remove(listener); + Iterator proxies = fModelProxies.values().iterator(); + while (proxies.hasNext()) { + IModelProxy proxy = (IModelProxy) proxies.next(); + proxy.removeModelChangedListener(listener); + } + } + + /** + * Returns the element corresponding to the given tree path. + * + * @param path tree path + * @return model element + */ + protected Object getElement(TreePath path) { + if (path.getSegmentCount() > 0) { + return path.getLastSegment(); + } + return getViewer().getInput(); + } +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java new file mode 100644 index 000000000..ba19a4f23 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java @@ -0,0 +1,414 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.IBasicPropertyConstants; +import org.eclipse.jface.viewers.ILazyTreePathContentProvider; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.progress.UIJob; + +/** + * Content provider for a virtual tree. + * + * @since 3.3 + */ +class TreeModelContentProvider extends ModelContentProvider implements ILazyTreePathContentProvider { + + protected static final String[] STATE_PROPERTIES = new String[]{IBasicPropertyConstants.P_TEXT, IBasicPropertyConstants.P_IMAGE}; + + /** + * Map of parent paths to requests + */ + private Map fPendingChildRequests = new HashMap(); + + /** + * Map of content adapters to requests + */ + private Map fPendingCountRequests = new HashMap(); + + /** + * Map of content adapters to requests + */ + private Map fPendingHasChildrenRequests = new HashMap(); + + private Timer fTimer = new Timer(); + + /** + * Re-filters any filtered children of the given parent element. + * + * @param path parent element + */ + protected void refilterChildren(TreePath path) { + if (getViewer() != null) { + int[] filteredChildren = getFilteredChildren(path); + if (filteredChildren != null) { + for (int i = 0; i < filteredChildren.length; i++) { + doUpdateElement(path, filteredChildren[i]); + } + } + } + } + + protected synchronized void doUpdateChildCount(TreePath path) { + Object element = getElement(path); + IElementContentProvider contentAdapter = getContentAdapter(element); + if (contentAdapter != null) { + ChildrenCountUpdate request = (ChildrenCountUpdate) fPendingCountRequests.get(contentAdapter); + if (request != null) { + if (request.coalesce(path)) { + return; + } else { + request.start(); + } + } + final ChildrenCountUpdate newRequest = new ChildrenCountUpdate(this, contentAdapter); + newRequest.coalesce(path); + fPendingCountRequests.put(contentAdapter, newRequest); + fTimer.schedule(new TimerTask() { + public void run() { + newRequest.start(); + } + }, 10L); + } + } + + protected synchronized void doUpdateElement(TreePath parentPath, int modelIndex) { + ChildrenUpdate request = (ChildrenUpdate) fPendingChildRequests.get(parentPath); + if (request != null) { + if (request.coalesce(modelIndex)) { + return; + } else { + request.start(); + } + } + Object parent = getElement(parentPath); + IElementContentProvider contentAdapter = getContentAdapter(parent); + if (contentAdapter != null) { + final ChildrenUpdate newRequest = new ChildrenUpdate(this, parentPath, modelIndex, contentAdapter); + fPendingChildRequests.put(parentPath, newRequest); + fTimer.schedule(new TimerTask() { + public void run() { + newRequest.start(); + } + }, 10L); + } + } + + protected synchronized void doUpdateHasChildren(TreePath path) { + Object element = getElement(path); + IElementContentProvider contentAdapter = getContentAdapter(element); + if (contentAdapter != null) { + HasChildrenUpdate request = (HasChildrenUpdate) fPendingHasChildrenRequests.get(contentAdapter); + if (request != null) { + if (request.coalesce(path)) { + return; + } else { + request.start(); + } + } + final HasChildrenUpdate newRequest = new HasChildrenUpdate(this, contentAdapter); + newRequest.coalesce(path); + fPendingHasChildrenRequests.put(contentAdapter, newRequest); + fTimer.schedule(new TimerTask() { + public void run() { + newRequest.start(); + } + }, 10L); + } + } + + protected synchronized void childRequestStarted(IChildrenUpdate update) { + fPendingChildRequests.remove(update.getParent()); + } + + protected synchronized void countRequestStarted(Object key) { + fPendingCountRequests.remove(key); + } + + protected synchronized void hasChildrenRequestStarted(Object key) { + fPendingHasChildrenRequests.remove(key); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#getPresentationContext() + */ + protected IPresentationContext getPresentationContext() { + return ((TreeModelViewer)getViewer()).getPresentationContext(); + } + + /** + * Returns the tree viewer this content provider is working for + * + * @return tree viewer + */ + protected TreeViewer getTreeViewer() { + return (TreeViewer)getViewer(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleAdd(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta) + */ + protected void handleAdd(IModelDelta delta) { + doUpdateChildCount(getViewerTreePath(delta.getParentDelta())); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleContent(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta) + */ + protected void handleContent(IModelDelta delta) { + if (delta.getChildCount() == 0) { + // if the delta is for the root, ensure the root still matches viewer input + if (!delta.getElement().equals(getViewer().getInput())) { + return; + } + } + TreePath treePath = getViewerTreePath(delta); + cancelSubtreeUpdates(treePath); + getTreeViewer().refresh(getElement(treePath)); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleExpand(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta) + */ + protected void handleExpand(IModelDelta delta) { + // expand each parent, then this node + IModelDelta parentDelta = delta.getParentDelta(); + if (parentDelta != null) { + handleExpand(parentDelta); + expand(delta); + } + } + + protected void expand(IModelDelta delta) { + int childCount = delta.getChildCount(); + int modelIndex = delta.getIndex(); + TreeViewer treeViewer = getTreeViewer(); + if (modelIndex >= 0) { + int viewIndex = modelToViewIndex(getViewerTreePath(delta.getParentDelta()), modelIndex); + if (DEBUG_CONTENT_PROVIDER) { + System.out.println("[expand] replace(" + delta.getParentDelta().getElement() + ", (model) " + modelIndex + " (view) " + viewIndex + ", " + delta.getElement()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + treeViewer.replace(delta.getParentDelta().getElement(), viewIndex, delta.getElement()); + } + if (childCount > 0) { + TreePath elementPath = getViewerTreePath(delta); + int viewCount = modelToViewChildCount(elementPath, childCount); + if (DEBUG_CONTENT_PROVIDER) { + System.out.println("[expand] setChildCount(" + delta.getElement() + ", (model) " + childCount + " (view) " + viewCount); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + treeViewer.setChildCount(delta.getElement(), viewCount); + if (!treeViewer.getExpandedState(elementPath)) { + treeViewer.expandToLevel(elementPath, 1); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleInsert(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta) + */ + protected void handleInsert(IModelDelta delta) { + // TODO: filters + getTreeViewer().insert(getViewerTreePath(delta.getParentDelta()), delta.getElement(), delta.getIndex()); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleRemove(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta) + */ + protected void handleRemove(IModelDelta delta) { + getTreeViewer().remove(getViewerTreePath(delta)); + // refresh the parent to properly update for non-visible/unmapped children + getTreeViewer().refresh(delta.getParentDelta().getElement()); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleReplace(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta) + */ + protected void handleReplace(IModelDelta delta) { + getTreeViewer().replace(delta.getParentDelta().getElement(), delta.getIndex(), delta.getElement()); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleSelect(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta) + */ + protected void handleSelect(IModelDelta delta) { + int modelIndex = delta.getIndex(); + TreeViewer treeViewer = getTreeViewer(); + if (modelIndex >= 0) { + int viewIndex = modelToViewIndex(getViewerTreePath(delta.getParentDelta()), modelIndex); + if (DEBUG_CONTENT_PROVIDER) { + System.out.println("[select] replace(" + delta.getParentDelta().getElement() + ", (model) " + modelIndex + " (view) " + viewIndex + ", " + delta.getElement()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + treeViewer.replace(delta.getParentDelta().getElement(), viewIndex, delta.getElement()); + } + treeViewer.setSelection(new TreeSelection(getViewerTreePath(delta))); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#handleState(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta) + */ + protected void handleState(IModelDelta delta) { + getTreeViewer().update(delta.getElement(), STATE_PROPERTIES); + } + + public synchronized void dispose() { + fTimer.cancel(); + fPendingChildRequests.clear(); + fPendingCountRequests.clear(); + super.dispose(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#buildViewerState(org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta) + */ + protected void buildViewerState(ModelDelta delta) { + Tree tree = (Tree) getViewer().getControl(); + TreeItem[] selection = tree.getSelection(); + Set set = new HashSet(); + for (int i = 0; i < selection.length; i++) { + set.add(selection[i]); + } + TreeItem[] items = tree.getItems(); + for (int i = 0; i < items.length; i++) { + buildViewerState(delta, items[i], set); + } + } + + /** + * @param delta parent delta to build on + * @param item item + * @param set set of selected tree items + */ + private void buildViewerState(ModelDelta delta, TreeItem item, Set set) { + Object element = item.getData(); + if (element != null) { + boolean expanded = item.getExpanded(); + boolean selected = set.contains(item); + if (expanded || selected) { + int flags = IModelDelta.NO_CHANGE; + if (expanded) { + flags = flags | IModelDelta.EXPAND; + } + if (selected) { + flags = flags | IModelDelta.SELECT; + } + ModelDelta childDelta = delta.addNode(element, flags); + if (expanded) { + TreeItem[] items = item.getItems(); + for (int i = 0; i < items.length; i++) { + buildViewerState(childDelta, items[i], set); + } + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.ModelContentProvider#doInitialRestore() + */ + protected void doInitialRestore() { + Tree tree = (Tree) getViewer().getControl(); + TreeItem[] items = tree.getItems(); + for (int i = 0; i < items.length; i++) { + TreeItem item = items[i]; + Object data = item.getData(); + if (data != null) { + doRestore(new TreePath(new Object[]{data})); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILazyTreePathContentProvider#getParents(java.lang.Object) + */ + public TreePath[] getParents(Object element) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILazyTreePathContentProvider#updateChildCount(org.eclipse.jface.viewers.TreePath, int) + */ + public synchronized void updateChildCount(TreePath treePath, int currentChildCount) { + if (DEBUG_CONTENT_PROVIDER) { + System.out.println("updateChildCount(" + getElement(treePath) + ", " + currentChildCount + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + refilterChildren(treePath); + //re-filter children when asked to update the child count for an element (i.e. + // when refreshing, see if filtered children are still filtered) + doUpdateChildCount(treePath); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILazyTreePathContentProvider#updateElement(org.eclipse.jface.viewers.TreePath, int) + */ + public synchronized void updateElement(TreePath parentPath, int viewIndex) { + int modelIndex = viewToModelIndex(parentPath, viewIndex); + if (DEBUG_CONTENT_PROVIDER) { + System.out.println("updateElement("+ getElement(parentPath) + ", " + viewIndex + ") > modelIndex = " + modelIndex); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + doUpdateElement(parentPath, modelIndex); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILazyTreePathContentProvider#updateHasChildren(org.eclipse.jface.viewers.TreePath) + */ + public synchronized void updateHasChildren(TreePath path) { + if (DEBUG_CONTENT_PROVIDER) { + System.out.println("updateHasChildren(" + getElement(path)); //$NON-NLS-1$ + } + doUpdateHasChildren(path); + } + + /** + * @param delta + */ + void doRestore(final ModelDelta delta) { + if (delta.getFlags() != IModelDelta.NO_CHANGE) { + UIJob job = new UIJob("restore delta") { //$NON-NLS-1$ + public IStatus runInUIThread(IProgressMonitor monitor) { + TreePath treePath = getViewerTreePath(delta); + AbstractTreeViewer viewer = (AbstractTreeViewer)getViewer(); + if ((delta.getFlags() & IModelDelta.EXPAND) != 0) { + viewer.expandToLevel(treePath, 1); + } + if ((delta.getFlags() & IModelDelta.SELECT) != 0) { + viewer.setSelection(new TreeSelection(treePath)); + } + delta.setFlags(IModelDelta.NO_CHANGE); + checkIfRestoreComplete(); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + job.schedule(); + } + } +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelLabelProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelLabelProvider.java new file mode 100644 index 000000000..366603923 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelLabelProvider.java @@ -0,0 +1,240 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.jface.viewers.ViewerRow; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.progress.UIJob; + +/** + * @since 3.3 + */ +class TreeModelLabelProvider extends ColumnLabelProvider { + + private InternalTreeModelViewer fViewer; + private List fComplete; + + /** + * Cache of images used for elements in this label provider. Label updates + * use the method <code>getImage(...)</code> to cache images for + * image descriptors. The images are disposed with this label provider. + */ + private Map fImageCache = new HashMap(); + + /** + * Cache of the fonts used for elements in this label provider. Label updates + * use the method <code>getFont(...)</code> to cache fonts for + * FontData objects. The fonts are disposed with this label provider. + */ + private Map fFontCache = new HashMap(); + + /** + * Cache of the colors used for elements in this label provider. Label updates + * use the method <code>getColor(...)</code> to cache colors for + * RGB values. The colors are disposed with this label provider. + */ + private Map fColorCache = new HashMap(); + + /** + * Constructs a new label provider on the given display + */ + public TreeModelLabelProvider(InternalTreeModelViewer viewer) { + fViewer = viewer; + } + + /** + * Returns an image for the given image descriptor or <code>null</code>. Adds the image + * to a cache of images if it does not already exist. + * + * @param descriptor image descriptor or <code>null</code> + * @return image or <code>null</code> + */ + protected Image getImage(ImageDescriptor descriptor) { + if (descriptor == null) { + return null; + } + Image image = (Image) fImageCache.get(descriptor); + if (image == null) { + image = new Image(getDisplay(), descriptor.getImageData()); + fImageCache.put(descriptor, image); + } + return image; + } + + /** + * Returns the display to use for resource allocation. + * + * @return display + */ + private Display getDisplay() { + return fViewer.getControl().getDisplay(); + } + + /** + * Returns a font for the given font data or <code>null</code>. Adds the font to the font + * cache if not yet created. + * + * @param fontData font data or <code>null</code> + * @return font font or <code>null</code> + */ + protected Font getFont(FontData fontData) { + if (fontData == null) { + return null; + } + Font font = (Font) fFontCache.get(fontData); + if (font == null) { + font = new Font(getDisplay(), fontData); + fFontCache.put(fontData, font); + } + return font; + } + + /** + * Returns a color for the given RGB or <code>null</code>. Adds the color to the color + * cache if not yet created. + * + * @param rgb RGB or <code>null</code> + * @return color or <code>null</code> + */ + protected Color getColor(RGB rgb) { + if (rgb == null) { + return null; + } + Color color = (Color) fColorCache.get(rgb); + if (color == null) { + color = new Color(getDisplay(), rgb); + fColorCache.put(rgb, color); + } + return color; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.BaseLabelProvider#dispose() + */ + public void dispose() { + Iterator images = fImageCache.values().iterator(); + while (images.hasNext()) { + Image image = (Image) images.next(); + image.dispose(); + } + fImageCache.clear(); + + Iterator fonts = fFontCache.values().iterator(); + while (fonts.hasNext()) { + Font font = (Font) fonts.next(); + font.dispose(); + } + fFontCache.clear(); + + Iterator colors = fColorCache.values().iterator(); + while (colors.hasNext()) { + Color color = (Color) colors.next(); + color.dispose(); + } + fColorCache.clear(); + + super.dispose(); + } + + public synchronized void update(ViewerCell cell) { + // NOT USED - the viewer updates each row instead + } + + public synchronized void update(Object element, ViewerRow row) { + String[] visibleColumns = fViewer.getVisibleColumns(); + IElementLabelProvider presentation = getLabelAdapter(element); + if (presentation != null) { + presentation.update(new LabelUpdate(element, (TreeItem) row.getItem(), this, visibleColumns)); + } else if (element instanceof String) { + // for example, expression error messages + row.setText(0, (String)element); + } + } + + /** + * Returns the presentation context for this label provider. + * + * @return presentation context + */ + protected IPresentationContext getPresentationContext() { + return fViewer.getPresentationContext(); + } + + /** + * Returns the label provider for the given element or + * <code>null</code> if none. + * + * @param element + * element to retrieve adapter for + * @return label adapter or <code>null</code> + */ + protected IElementLabelProvider getLabelAdapter(Object element) { + IElementLabelProvider adapter = null; + if (element instanceof IElementLabelProvider) { + adapter = (IElementLabelProvider) element; + } else if (element instanceof IAdaptable) { + IAdaptable adaptable = (IAdaptable) element; + adapter = (IElementLabelProvider) adaptable.getAdapter(IElementLabelProvider.class); + } + return adapter; + } + + /** + * A label update is complete. + * + * @param update + */ + protected synchronized void complete(ILabelUpdate update) { + if (fComplete == null) { + fComplete = new ArrayList(); + UIJob job = new UIJob(getDisplay(), "Label Updates") { //$NON-NLS-1$ + public IStatus runInUIThread(IProgressMonitor monitor) { + LabelUpdate[] updates = null; + synchronized (TreeModelLabelProvider.this) { + updates = (LabelUpdate[]) fComplete.toArray(new LabelUpdate[fComplete.size()]); + fComplete = null; + } + //System.out.println("Changed Labels: " + updates.length); + for (int i = 0; i < updates.length; i++) { + updates[i].update(); + } + return Status.OK_STATUS; + } + }; + job.setSystem(true); + job.schedule(10L); + } + fComplete.add(update); + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ViewerUpdateMonitor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ViewerUpdateMonitor.java new file mode 100644 index 000000000..8014e05a3 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ViewerUpdateMonitor.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.debug.internal.ui.commands.actions.AbstractRequestMonitor; +import org.eclipse.debug.internal.ui.viewers.AsynchronousSchedulingRuleFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.ui.progress.WorkbenchJob; + +/** + * @since 3.3 + */ +abstract class ViewerUpdateMonitor extends AbstractRequestMonitor implements IViewerUpdate { + + private ModelContentProvider fContentProvider; + + /** + * Whether this request's 'done' method has been called. + */ + private boolean fDone = false; + + protected WorkbenchJob fViewerUpdateJob = new WorkbenchJob("Asynchronous viewer update") { //$NON-NLS-1$ + public IStatus runInUIThread(IProgressMonitor monitor) { + // necessary to check if viewer is disposed + try { + if (!isCanceled() && !getContentProvider().isDisposed()) { + IStatus status = getStatus(); + if (status == null || status.isOK()) { + performUpdate(); + } + } + } finally { + getContentProvider().updateComplete(ViewerUpdateMonitor.this); + } + return Status.OK_STATUS; + } + }; + + /** + * Constructs an update for the given content provider + * + * @param contentProvider content provider + */ + public ViewerUpdateMonitor(ModelContentProvider contentProvider) { + fContentProvider = contentProvider; + // serialize updates per viewer + fViewerUpdateJob.setRule(getUpdateSchedulingRule()); + fViewerUpdateJob.setSystem(true); + contentProvider.updateStarted(this); + } + + /** + * Returns the scheduling rule for viewer update job. + * + * @return rule or <code>null</code> + */ + protected ISchedulingRule getUpdateSchedulingRule() { + return AsynchronousSchedulingRuleFactory.getDefault().newSerialPerObjectRule(getContentProvider()); + } + + /** + * Returns the model content provider this update is being performed for. + * + * @return the model content provider this update is being performed for + */ + protected ModelContentProvider getContentProvider() { + return fContentProvider; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IProgressMonitor#done() + */ + public final void done() { + synchronized (this) { + fDone = true; + } + scheduleViewerUpdate(0L); + } + + /** + * Returns whether this request is done yet. + * + * @return + */ + protected synchronized boolean isDone() { + return fDone; + } + + protected void scheduleViewerUpdate(long ms) { + if(!isCanceled()) { + fViewerUpdateJob.schedule(ms); + } else { + getContentProvider().updateComplete(this); + } + } + + /** + * Notification this update has been completed and should now be applied to + * this update's viewer. This method is called in the UI thread. + */ + protected abstract void performUpdate(); + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate#getPresentationContext() + */ + public IPresentationContext getPresentationContext() { + return fContentProvider.getPresentationContext(); + } + + public Object getElement(TreePath path) { + return fContentProvider.getElement(path); + } + + /** + * Whether this update is rooted at or below the given path. + * + * @param path + * @return whether this update is rooted at or below the given path + */ + abstract boolean isContained(TreePath path); + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IChildrenCountUpdate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IChildrenCountUpdate.java new file mode 100644 index 000000000..9ea4246cd --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IChildrenCountUpdate.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +import org.eclipse.jface.viewers.TreePath; + + +/** + * Request monitor used to collect the number of children for an element in a viewer. + * + * @since 3.3 + */ +public interface IChildrenCountUpdate extends IViewerUpdate { + + /** + * Returns the parent elements that children counts have been requested for + * as tree paths. An empty path identifies the root element. + * + * @return parent elements as tree paths + */ + public TreePath[] getParents(); + + /** + * Sets the number of children for the given parent. + * + * @param parent parent element or empty path for root element + * @param numChildren number of children + */ + public void setChildCount(TreePath parentPath, int numChildren); +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IChildrenUpdate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IChildrenUpdate.java new file mode 100644 index 000000000..d477a2c0c --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IChildrenUpdate.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +import org.eclipse.jface.viewers.TreePath; + +/** + * Context sensitive children update request for a parent and subrange of its + * children. + * + * @since 3.3 + */ +public interface IChildrenUpdate extends IViewerUpdate { + + /** + * Returns the parent element that children are being requested for + * as a tree path. An empty path identifies the root element. + * + * @return parent element as a tree path + */ + public TreePath getParent(); + + /** + * Returns the offset at which children have been requested for. This is + * the index of the first child being requested. + * + * @return offset at which children have been requested for + */ + public int getOffset(); + + /** + * Returns the number of children requested. + * + * @return number of children requested + */ + public int getLength(); + + /** + * Sets the child for this request's parent at the given offset. + * + * @param child child + * @param index child offset + * + * TODO: what to do with <code>null</code> + */ + public void setChild(Object child, int offset); +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IColumnPresentation.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IColumnPresentation.java index 87447d94f..448dfc845 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IColumnPresentation.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IColumnPresentation.java @@ -8,7 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers.provisional; +package org.eclipse.debug.internal.ui.viewers.model.provisional; import org.eclipse.jface.resource.ImageDescriptor; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IColumnPresentationFactoryAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IColumnPresentationFactoryAdapter.java index c07fee16c..511b38b8b 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IColumnPresentationFactoryAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IColumnPresentationFactoryAdapter.java @@ -8,7 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers.provisional; +package org.eclipse.debug.internal.ui.viewers.model.provisional; /** * An adapter used to create column presentations. diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementCompareRequest.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementCompareRequest.java new file mode 100644 index 000000000..0a0d8c6bc --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementCompareRequest.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +import org.eclipse.ui.IMemento; + +/** + * Request to compare an element to a previously created memento. + * + * @since 3.3 + */ +public interface IElementCompareRequest extends IViewerUpdate { + + /** + * The element to compare against this request's memento. + * + * @return element + */ + public Object getElement(); + + /** + * The memento to compare this request's element. + * + * @return memento + */ + public IMemento getMemento(); + + /** + * Sets whether this request's memento represents this requests's element. + * + * @param equal whether the memento represents the element + */ + public void setEqual(boolean equal); +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementContentProvider.java new file mode 100644 index 000000000..19ee90d20 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementContentProvider.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + + +/** + * Provides content for an element in a virtual viewer. + * + * @since 3.3 + */ +public interface IElementContentProvider { + + /** + * Updates the number of children for the given parent elements in the + * specified request. + * + * @param update specifies counts to update and stores result + */ + public void update(IChildrenCountUpdate update); + + /** + * Updates children as requested by the update. + * + * @param update specifies children to update and stores result + */ + public void update(IChildrenUpdate update); + + /** + * Updates whether elements have children. + * + * @param update specifies elements to update and stores result + */ + public void update(IHasChildrenUpdate update); + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementEditor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementEditor.java new file mode 100644 index 000000000..7320bb58f --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementEditor.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.swt.widgets.Composite; + +/** + * Creates context specific cell modifiers and editors for an elements. + * + * @since 3.3 + */ +public interface IElementEditor { + + /** + * Returns a cell editor to use for the specified column and object or <code>null</code> + * if none. + * + * @param context presentation context + * @param id column id + * @param element object to be edited + * @param parent parent control to create the cell editor in + * @return cell editor or <code>null</code> + */ + public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent); + + /** + * Returns a cell modifier for the specified element in the given context + * or <code>null</code> if none. + * + * @return cell modifier or <code>null</code> + */ + public ICellModifier getCellModifier(IPresentationContext context, Object element); + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementLabelProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementLabelProvider.java new file mode 100644 index 000000000..56717e5a5 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementLabelProvider.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +/** + * Provides context sensitive labels. Can be registered as an adapter for an element, + * or implemented directly. + * + * @since 3.3 + */ +public interface IElementLabelProvider { + + /** + * Updates the specified label. + * + * @param update specifies the element and context for which a label is requested and + * stores updated label attributes + */ + public void update(ILabelUpdate update); +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementMementoProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementMementoProvider.java new file mode 100644 index 000000000..4261d1410 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementMementoProvider.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +/** + * Used to save and restore viewer selection/expansion state. A memento + * provider adapter should be available from a viewer input element + * in order to support viewer state save/restore. + * + * @since 3.3 + */ +public interface IElementMementoProvider { + + /** + * Creates and stores a memento for the element specified in the request. + * The request should be cancelled if a memento is not supported for the + * specified element or context. + * + * @param request specifies element and provides memento store + */ + public void encodeElement(IElementMementoRequest request); + + /** + * Determines if a memento represents the element specified in the request. + * + * @param request specifies element and previously created memento + */ + public void compareElement(IElementCompareRequest request); + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementMementoRequest.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementMementoRequest.java new file mode 100644 index 000000000..51719f021 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IElementMementoRequest.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +import org.eclipse.ui.IMemento; + +/** + * Request to store a memento for an element in a specific context. + * + * @since 3.3 + */ +public interface IElementMementoRequest extends IViewerUpdate { + + /** + * Returns the element for which the memento has been requested. + * + * @return element + */ + public Object getElement(); + + /** + * Returns the memento used to persist the element. + * + * @return memento + */ + public IMemento getMemento(); +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IHasChildrenUpdate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IHasChildrenUpdate.java new file mode 100644 index 000000000..9dc602174 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IHasChildrenUpdate.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +import org.eclipse.jface.viewers.TreePath; + +/** + * Context sensitive update request for whether elements have children. + * + * @since 3.3 + */ +public interface IHasChildrenUpdate extends IViewerUpdate { + + /** + * The elements this request is for specified as tree paths. + * An empty path identifies the root element. + * + * @return elements as tree paths + */ + public TreePath[] getElements(); + + /** + * Sets whether the given element has children. + * + * @param element tree path to element, or empty for root element + * @param hasChildren whether it has children + */ + public void setHasChilren(TreePath element, boolean hasChildren); +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/ILabelUpdate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/ILabelUpdate.java new file mode 100644 index 000000000..fb2e414a9 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/ILabelUpdate.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; + +/** + * Context sensitive label update request for an element. + * + * @since 3.3 + */ +public interface ILabelUpdate extends IViewerUpdate { + + /** + * Returns the element the label update is for. + * + * @return associated element + */ + public Object getElement(); + + /** + * Returns the id's of the visible columns in presentation order, + * or <code>null</code> if none. + * + * @return column id's or <code>null</code> + */ + public String[] getColumnIds(); + + /** + * Sets the text of the label of the specified column. Cannot be <code>null</code>. + * + * @param text + * @param columnIndex column index (0 when no columns) + */ + public void setLabel(String text, int columnIndex); + + /** + * Sets the font of the label. + * + * @param fontData + * @param columnIndex column index (0 when no columns) + */ + public void setFontData(FontData fontData, int columnIndex); + + /** + * Sets the image of the label. + * + * @param image + * @param columnIndex column index (0 when no columns) + */ + public void setImageDescriptor(ImageDescriptor image, int columnIndex); + + /** + * Sets the foreground color of the label. + * + * @param foreground + * @param columnIndex column index (0 when no columns) + */ + public void setForeground(RGB foreground, int columnIndex); + + /** + * Sets the background color of the label. + * + * @param background + * @param columnIndex column index (0 when no columns) + */ + public void setBackground(RGB background, int columnIndex); +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IModelChangedListener.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelChangedListener.java index 5b0a2b4b5..f812ee94b 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IModelChangedListener.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelChangedListener.java @@ -8,7 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers.provisional; +package org.eclipse.debug.internal.ui.viewers.model.provisional; /** * A model changed listener is notified of changes in a model. A model @@ -24,7 +24,8 @@ public interface IModelChangedListener { * Notification a model has changed as described by the given delta. * * @param delta model delta + * @param proxy proxy that created the delta */ - public void modelChanged(IModelDelta delta); + public void modelChanged(IModelDelta delta, IModelProxy proxy); } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IModelDelta.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelDelta.java index d945086ae..f55ec30fd 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IModelDelta.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelDelta.java @@ -8,7 +8,8 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers.provisional; +package org.eclipse.debug.internal.ui.viewers.model.provisional; + /** @@ -84,13 +85,26 @@ public interface IModelDelta { * Suggests that the element should be selected, as described by its path. */ public static int SELECT = 1 << 21; + + /** + * Indicates a model proxy should be installed for the given element + * @since 3.3 + */ + public static int INSTALL = 1 << 22; + + /** + * Indicates a model proxy should be uninstalled for the given element + * @since 3.3 + */ + public static int UNINSTALL = 1 << 23; + /** * Returns the parent of this node, or <code>null</code> if this is * a root node. * * @return parent node or <code>null</code> if this is a root node */ - public IModelDelta getParent(); + public IModelDelta getParentDelta(); /** * Returns the model element this node describes. @@ -112,7 +126,7 @@ public interface IModelDelta { * * @return changed children, possibly empty */ - public ModelDelta[] getNodes(); + public ModelDelta[] getChildDeltas(); /** * When a node indicates the <code>IModelDelta.REPLACED</code> flag, this method @@ -123,12 +137,35 @@ public interface IModelDelta { public Object getReplacementElement(); /** + * Returns this node's index in its parents child collection or -1 if unknown. + * This attribute is required when expanding or selecting an element. + * <p> * When a node indicates the <code>IModelDelta.INSERTED</code> flag, this method * returns the index that the new element should be inserted at relative to its * parents children, otherwise -1. - * + * </p> * @return insertion index or -1 */ public int getIndex(); + /** + * Returns the total number of children this element has, or -1 if unknown. Note + * that this number may be greater than the number of child delta nodes for this + * node, since not all children may be reporting deltas. + * <p> + * This attribute is required when expanding or selecting an element. + * </p> + * + * @return total number of child elements this element has + */ + public int getChildCount(); + + /** + * Accepts the given visitor. + * + * @param visitor + * @since 3.3 + */ + public void accept(IModelDeltaVisitor visitor); + } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelDeltaVisitor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelDeltaVisitor.java new file mode 100644 index 000000000..1d4154651 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelDeltaVisitor.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + + +/** + * An objects that visits model deltas. + * + * @since 3.3 + */ +public interface IModelDeltaVisitor { + + /** + * Visits the given model delta. + * + * @param delta the delta to visit + * @param depth depth in the delta where 0 == root node + * @return <code>true</code> if the model delta's children should + * be visited; <code>false</code> if they should be skipped. + */ + public boolean visit(IModelDelta delta, int depth); + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IModelProxy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelProxy.java index b88c7b497..6b91cad7a 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IModelProxy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelProxy.java @@ -8,7 +8,9 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers.provisional; +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +import org.eclipse.jface.viewers.Viewer; /** * A model proxy represents a model for a specific presentation context and @@ -46,15 +48,17 @@ public interface IModelProxy { public void init(IPresentationContext context); /** - * Notification this model proxy has been installed in its presentation - * context. This indicates that the model proxy has been created and registered + * Notification this model proxy has been installed in the specified + * viewer. This indicates that the model proxy has been created and registered * model change listeners are ready to process deltas. * <p> * This method is called by the asynchronous viewer framework and should not * be called by clients. * </p> + * @param viewer viewer + * @since 3.3 */ - public void installed(); + public void installed(Viewer viewer); /** * Disposes this model proxy. @@ -79,4 +83,12 @@ public interface IModelProxy { */ public void removeModelChangedListener(IModelChangedListener listener); + /** + * Returns whether this proxy has been disposed. + * + * @return whether this proxy has been disposed + * @since 3.3 + */ + public boolean isDisposed(); + } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IModelProxyFactoryAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelProxyFactoryAdapter.java index 8127e4a0a..e3e3b8f55 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IModelProxyFactoryAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelProxyFactoryAdapter.java @@ -8,7 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers.provisional; +package org.eclipse.debug.internal.ui.viewers.model.provisional; /** * A model proxy factory creates model proxies for elements based on diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IModelSelectionPolicy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelSelectionPolicy.java index f64450e5e..951342465 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IModelSelectionPolicy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelSelectionPolicy.java @@ -8,7 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers.provisional; +package org.eclipse.debug.internal.ui.viewers.model.provisional; import org.eclipse.jface.viewers.ISelection; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IModelSelectionPolicyFactoryAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelSelectionPolicyFactoryAdapter.java index 71f7d2b47..76ea4bbb1 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IModelSelectionPolicyFactoryAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IModelSelectionPolicyFactoryAdapter.java @@ -8,7 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers.provisional; +package org.eclipse.debug.internal.ui.viewers.model.provisional; /** diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IPresentationContext.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IPresentationContext.java index dc96f3228..fca304e53 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IPresentationContext.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IPresentationContext.java @@ -8,10 +8,9 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers.provisional; +package org.eclipse.debug.internal.ui.viewers.model.provisional; import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.ui.IWorkbenchPart; /** * Context in which an asynchronous request has been made. @@ -30,15 +29,6 @@ public interface IPresentationContext { public static final String PROPERTY_COLUMNS = "PROPERTY_COLUMNS"; //$NON-NLS-1$ /** - * Returns the part for which a request is being made - * or <code>null</code> if none. - * - * @return the part for which a request is being made - * or <code>null</code> - */ - public IWorkbenchPart getPart(); - - /** * Returns identifiers of the visible columns in the order * labels should be provided, or <code>null</code> if columns * are not being displayed. Label providers use this @@ -73,4 +63,27 @@ public interface IPresentationContext { */ public String getId(); + /** + * Sets the specified property and notifies listeners of changes. + * + * @param property property name + * @param value property value + */ + public void setProperty(String property, Object value); + + /** + * Returns the property with the specified name or <code>null</code> + * if none. + * + * @param property property name + * @return property value or <code>null</code> + */ + public Object getProperty(String property); + + /** + * Disposes this presentation context. Called by the framework + * when the associated viewer is disposed. + */ + public void dispose(); + } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IViewerUpdate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IViewerUpdate.java new file mode 100644 index 000000000..911677413 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IViewerUpdate.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.viewers.TreePath; + +/** + * A context sensitive viewer update request. + * + * @since 3.3 + */ +public interface IViewerUpdate extends IProgressMonitor { + + /** + * Returns the context this update was requested in. + * + * @return context this update was requested in + */ + public IPresentationContext getPresentationContext(); + + /** + * Sets the status of this request, possibly <code>null</code>. + * When a request fails, the status indicates why the request failed. + * A <code>null</code> status is considered to be successful. + * + * @param status request status + */ + public void setStatus(IStatus status); + + /** + * Returns the status of this request, or <code>null</code>. + * + * @return request status or <code>null</code> + */ + public IStatus getStatus(); + + /** + * Returns the model element corresponding to the given tree path. + * Returns the root element for the empty path. + * + * @param path viewer tree path + * @return corresponding model element + */ + public Object getElement(TreePath path); +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IViewerUpdateListener.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IViewerUpdateListener.java new file mode 100644 index 000000000..f196a5284 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/IViewerUpdateListener.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +import org.eclipse.debug.ui.commands.IStatusMonitor; + +/** + * Notified of viewer updates. + * + * @since 3.3 + */ +public interface IViewerUpdateListener { + + /** + * Notification that a sequence of viewer updates are starting. + */ + public void viewerUpdatesBegin(); + + /** + * Notification that viewer updates are complete. Corresponds to + * a <code>viewerUpdatesBegin()</code> notification. + */ + public void viewerUpdatesComplete(); + + /** + * Notification that a specific update has started within + * a sequence of updates. + * + * @param update update + */ + public void updateStarted(IStatusMonitor update); + + /** + * Notification that a specific update has completed within a + * sequence of updates. + * + * @param update update + */ + public void updateComplete(IStatusMonitor update); +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/ModelDelta.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/ModelDelta.java index 7fe6d8e0c..f4ceedd0f 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/ModelDelta.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/ModelDelta.java @@ -8,7 +8,8 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers.provisional; +package org.eclipse.debug.internal.ui.viewers.model.provisional; + @@ -27,7 +28,8 @@ public class ModelDelta implements IModelDelta { private int fFlags; private ModelDelta[] fNodes = EMPTY_NODES; private Object fReplacement; - private int fIndex; + private int fIndex = -1; + private int fChildCount = -1; private static final ModelDelta[] EMPTY_NODES = new ModelDelta[0]; /** @@ -68,6 +70,22 @@ public class ModelDelta implements IModelDelta { fIndex = index; fFlags = flags; } + + /** + * Constructs a new delta for the given element at the specified index + * relative to its parent with the given number of children. + * + * @param element model element + * @param index insertion position + * @param flags change flags + * @param childCount number of children this node has + */ + public ModelDelta(Object element, int index, int flags, int childCount) { + fElement = element; + fIndex = index; + fFlags = flags; + fChildCount = childCount; + } /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getElement() @@ -132,6 +150,23 @@ public class ModelDelta implements IModelDelta { } /** + * Adds a child delta to this delta at the specified index with the + * given number of children, and returns the newly created child delta. + * + * @param element child element in insert + * @param index index of the element relative to parent + * @param flags change flags + * @param numChildren the number of children the element has + * @return newly created child delta + */ + public ModelDelta addNode(Object element, int index, int flags, int numChildren) { + ModelDelta node = new ModelDelta(element, index, flags, numChildren); + node.setParent(this); + addDelta(node); + return node; + } + + /** * Sets the parent delta of this delta * * @param node parent delta @@ -143,7 +178,7 @@ public class ModelDelta implements IModelDelta { /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getParent() */ - public IModelDelta getParent() { + public IModelDelta getParentDelta() { return fParent; } @@ -164,7 +199,7 @@ public class ModelDelta implements IModelDelta { /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.IModelDelta#getNodes() */ - public ModelDelta[] getNodes() { + public ModelDelta[] getChildDeltas() { return fNodes; } @@ -220,11 +255,63 @@ public class ModelDelta implements IModelDelta { if ((flags & IModelDelta.STATE) > 0) { buf.append("STATE | "); //$NON-NLS-1$ } + if ((flags & IModelDelta.INSTALL) > 0) { + buf.append("INSTALL | "); //$NON-NLS-1$ + } + if ((flags & IModelDelta.UNINSTALL) > 0) { + buf.append("UNINSTALL | "); //$NON-NLS-1$ + } } buf.append('\n'); - ModelDelta[] nodes = delta.getNodes(); + buf.append("\t\tIndex: "); //$NON-NLS-1$ + buf.append(delta.fIndex); + buf.append(" Child Count: "); //$NON-NLS-1$ + buf.append(delta.fChildCount); + buf.append('\n'); + ModelDelta[] nodes = delta.getChildDeltas(); for (int i = 0; i < nodes.length; i++) { appendDetail(buf, nodes[i]); } } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta#getChildCount() + */ + public int getChildCount() { + return fChildCount; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta#accept(org.eclipse.debug.internal.ui.viewers.provisional.IModelDeltaVisitor) + */ + public void accept(IModelDeltaVisitor visitor) { + doAccept(visitor, 0); + } + + protected void doAccept(IModelDeltaVisitor visitor, int depth) { + if (visitor.visit(this, depth)) { + ModelDelta[] childDeltas = getChildDeltas(); + for (int i = 0; i < childDeltas.length; i++) { + childDeltas[i].doAccept(visitor, depth+1); + } + } + } + + /** + * Sets this delta's element + * + * @param element + */ + public void setElement(Object element) { + fElement = element; + } + + /** + * Sets this delta's flags. + * + * @param flags + */ + public void setFlags(int flags) { + fFlags = flags; + } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/PresentationContext.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/PresentationContext.java index 24c0549f9..368701179 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/PresentationContext.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/PresentationContext.java @@ -8,15 +8,16 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers; +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +import java.util.HashMap; +import java.util.Map; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.util.SafeRunnable; -import org.eclipse.ui.IWorkbenchPart; /** * Presentation context. @@ -27,22 +28,9 @@ import org.eclipse.ui.IWorkbenchPart; */ public class PresentationContext implements IPresentationContext { - private IWorkbenchPart fPart; private String fId; - private String[] fColumns; private ListenerList fListeners = new ListenerList(); - - /** - * Constructs a presentation context for the given part. - * - * @param part workbench part - */ - public PresentationContext(IWorkbenchPart part) { - fPart = part; - if (part != null) { - fId = part.getSite().getId(); - } - } + private Map fProperties = new HashMap(); /** * Constructs a presentation context for the given id. @@ -53,18 +41,11 @@ public class PresentationContext implements IPresentationContext { fId = id; } - /* (non-Javadoc) - * @see org.eclipse.debug.ui.viewers.IPresentationContext#getPart() - */ - public IWorkbenchPart getPart() { - return fPart; - } - /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext#getColumns() */ public String[] getColumns() { - return fColumns; + return (String[]) getProperty(IPresentationContext.PROPERTY_COLUMNS); } /** @@ -94,18 +75,17 @@ public class PresentationContext implements IPresentationContext { * * @param ids column identifiers */ - protected void setColumns(String[] ids) { - String[] oldValue = fColumns; - fColumns = ids; - firePropertyChange(IPresentationContext.PROPERTY_COLUMNS, oldValue, ids); + public void setColumns(String[] ids) { + setProperty(IPresentationContext.PROPERTY_COLUMNS, ids); } - /** - * Disposes this presentation context. + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext#dispose() */ - protected void dispose() { + public void dispose() { fListeners.clear(); - fPart = null; + fProperties.clear(); } /* (non-Javadoc) @@ -129,4 +109,34 @@ public class PresentationContext implements IPresentationContext { return fId; } + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext#getProperty(java.lang.String) + */ + public Object getProperty(String property) { + synchronized (fProperties) { + return fProperties.get(property); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext#setProperty(java.lang.String, java.lang.Object) + */ + public void setProperty(String property, Object value) { + synchronized (fProperties) { + Object oldValue = fProperties.get(property); + if (!isEqual(oldValue, value)) { + fProperties.put(property, value); + firePropertyChange(property, oldValue, value); + } + } + } + + private boolean isEqual(Object a, Object b) { + if (a == null) { + return b == null; + } + return a.equals(b); + } + + } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/TreeModelViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/TreeModelViewer.java new file mode 100644 index 000000000..e0af4d25d --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/provisional/TreeModelViewer.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers.model.provisional; + +import org.eclipse.debug.internal.ui.viewers.model.InternalTreeModelViewer; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IMemento; + +/** + * A tree viewer for a model. + * <p> + * Clients may instantiate this class. Clients may not subclass this class. + * </p> + * @since 3.3 + */ +public final class TreeModelViewer extends InternalTreeModelViewer { + + /** + * Constructs a new viewer. + * + * @param parent parent widget + * @param style viewer style bits + * @param context presentation context + */ + public TreeModelViewer(Composite parent, int style, IPresentationContext context) { + super(parent, style, context); + } + + /** + * Returns this viewer's presentation context. + * + * @return presentation context + */ + public IPresentationContext getPresentationContext() { + return super.getPresentationContext(); + } + + /** + * Registers the given listener for model delta notification. + * + * @param listener model delta listener + */ + public void addModelChangedListener(IModelChangedListener listener) { + super.addModelChangedListener(listener); + } + + /** + * Unregisters the given listener from model delta notification. + * + * @param listener model delta listener + */ + public void removeModelChangedListener(IModelChangedListener listener) { + super.removeModelChangedListener(listener); + } + + /** + * Registers the specified listener for view update notifications. + * + * @param listener listener + */ + public void addViewerUpdateListener(IViewerUpdateListener listener) { + super.addViewerUpdateListener(listener); + } + + /** + * Removes the specified listener from update notifications. + * + * @param listener listener + */ + public void removeViewerUpdateListener(IViewerUpdateListener listener) { + super.removeViewerUpdateListener(listener); + } + + /** + * Returns whether columns can be toggled on/off for this viewer's current + * input element. + * + * @return whether columns can be toggled on/off + */ + public boolean canToggleColumns() { + return super.canToggleColumns(); + } + + /** + * Returns the current column presentation for this viewer, or <code>null</code> + * if none. + * + * @return column presentation or <code>null</code> + */ + public IColumnPresentation getColumnPresentation() { + return super.getColumnPresentation(); + } + + /** + * Returns identifiers of the visible columns in this viewer, or <code>null</code> + * if there are currently no columns. + * + * @return visible columns identifiers or <code>null</code> + */ + public String[] getVisibleColumns() { + return super.getVisibleColumns(); + } + + /** + * Initializes viewer state from the memento + * + * @param memento + */ + public void initState(IMemento memento) { + super.initState(memento); + } + + /** + * Save viewer state into the given memento. + * + * @param memento + */ + public void saveState(IMemento memento) { + super.saveState(memento); + } + + /** + * Returns whether columns are being displayed currently. + * + * @return + */ + public boolean isShowColumns() { + return super.isShowColumns(); + } + + /** + * Resets any persisted column size for the given columns + */ + public void resetColumnSizes(String[] columnIds) { + super.resetColumnSizes(columnIds); + } + + /** + * Toggles columns on/off for the current column presentation, if any. + * + * @param show whether to show columns if the current input supports + * columns + */ + public void setShowColumns(boolean show) { + super.setShowColumns(show); + } + + /** + * Sets the visible columns for this viewer. Id's correspond to + * column identifiers from a column presentation. Use <code>null</code> to + * display default columns for the current column presentation. + * Only effects the current column presentation. + * + * @param ids column identifiers or <code>null</code> + */ + public void setVisibleColumns(String[] ids) { + super.setVisibleColumns(ids); + } +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AbstractColumnEditor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AbstractColumnEditor.java index 86687a456..d9bf4f414 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AbstractColumnEditor.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AbstractColumnEditor.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.debug.internal.ui.viewers.provisional; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + /** * Common function for a column editor. diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AbstractColumnPresentation.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AbstractColumnPresentation.java index fc4703866..1467375d0 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AbstractColumnPresentation.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AbstractColumnPresentation.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.debug.internal.ui.viewers.provisional; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.jface.resource.ImageDescriptor; /** diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AbstractModelProxy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AbstractModelProxy.java index 7608f3732..6311232e6 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AbstractModelProxy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AbstractModelProxy.java @@ -15,6 +15,11 @@ import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.viewers.Viewer; /** * Common function for a model proxy. @@ -26,6 +31,8 @@ import org.eclipse.debug.internal.ui.DebugUIPlugin; public abstract class AbstractModelProxy implements IModelProxy { private IPresentationContext fContext; + private Viewer fViewer; + private boolean fDisposed = false; private ListenerList fListeners = new ListenerList(); @@ -79,7 +86,7 @@ public abstract class AbstractModelProxy implements IModelProxy { } public void run() throws Exception { - listener.modelChanged(delta); + listener.modelChanged(delta, AbstractModelProxy.this); } }; @@ -91,7 +98,9 @@ public abstract class AbstractModelProxy implements IModelProxy { * @see org.eclipse.debug.internal.ui.viewers.IModelProxy#dispose() */ public synchronized void dispose() { + fDisposed = true; fContext = null; + fViewer = null; } /* (non-Javadoc) @@ -112,14 +121,29 @@ public abstract class AbstractModelProxy implements IModelProxy { } /* (non-Javadoc) + * * Subclasses should override as required. * - * @see org.eclipse.debug.internal.ui.viewers.IModelProxy#installed() + * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy#installed(org.eclipse.jface.viewers.Viewer) */ - public void installed() { + public void installed(Viewer viewer) { + fViewer = viewer; } + /** + * Returns the viewer this proxy is installed in. + * + * @return viewer or <code>null</code> if not installed + */ + protected Viewer getViewer() { + return fViewer; + } - + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy#isDisposed() + */ + public synchronized boolean isDisposed() { + return fDisposed; + } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AsynchronousContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AsynchronousContentAdapter.java index a66fc45a1..01635d16e 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AsynchronousContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AsynchronousContentAdapter.java @@ -18,6 +18,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.internal.ui.viewers.AsynchronousSchedulingRuleFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; /** * Abstract implementation of an asynchronous content adapter. @@ -56,7 +57,7 @@ public abstract class AsynchronousContentAdapter implements IAsynchronousContent * @return scheduling rule or <code>null</code> */ protected ISchedulingRule getRetrieveChildrenRule(Object parent, IPresentationContext context) { - return AsynchronousSchedulingRuleFactory.getDefault().newSerialPerPartRule(context); + return AsynchronousSchedulingRuleFactory.getDefault().newSerialPerObjectRule(context); } @@ -86,7 +87,7 @@ public abstract class AsynchronousContentAdapter implements IAsynchronousContent * @return scheduling rule or <code>null</code> */ protected ISchedulingRule getIsContainerRule(Object parent, IPresentationContext context) { - return AsynchronousSchedulingRuleFactory.getDefault().newSerialPerPartRule(context); + return AsynchronousSchedulingRuleFactory.getDefault().newSerialPerObjectRule(context); } /** diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AsynchronousLabelAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AsynchronousLabelAdapter.java index dfd1a8cf4..9ce1554b3 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AsynchronousLabelAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/AsynchronousLabelAdapter.java @@ -18,6 +18,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.internal.ui.viewers.AsynchronousSchedulingRuleFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.views.launch.DebugElementHelper; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.graphics.FontData; @@ -66,7 +67,7 @@ public abstract class AsynchronousLabelAdapter implements IAsynchronousLabelAdap * @return scheduling rule or <code>null</code> */ protected ISchedulingRule getLabelRule(Object element, IPresentationContext context) { - return AsynchronousSchedulingRuleFactory.getDefault().newSerialPerPartRule(context); + return AsynchronousSchedulingRuleFactory.getDefault().newSerialPerObjectRule(context); } /** diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IAsynchronousContentAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IAsynchronousContentAdapter.java index 33e92d647..faf3f89b9 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IAsynchronousContentAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IAsynchronousContentAdapter.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.debug.internal.ui.viewers.provisional; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + /** * Provides content for elements in an asynchronous viewer. Note that implementations * must provide content asynchronously. diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IAsynchronousLabelAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IAsynchronousLabelAdapter.java index 9ee685d2c..d17025d38 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IAsynchronousLabelAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IAsynchronousLabelAdapter.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.debug.internal.ui.viewers.provisional; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + /** * Provides labels for elements. Note that implementations * are must provide labels asynchronously. diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IColumnEditor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IColumnEditor.java index 075ef29f6..f31343e3c 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IColumnEditor.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IColumnEditor.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.debug.internal.ui.viewers.provisional; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.swt.widgets.Composite; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IColumnEditorFactoryAdapter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IColumnEditorFactoryAdapter.java index b24d25617..3dbc2186a 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IColumnEditorFactoryAdapter.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/provisional/IColumnEditorFactoryAdapter.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.debug.internal.ui.viewers.provisional; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + /** * An adapter used to column editors. Used in conjunction with a column presentation. * diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DebugEventHandler.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DebugEventHandler.java index fe26a476c..cd8d568ba 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DebugEventHandler.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DebugEventHandler.java @@ -12,9 +12,9 @@ package org.eclipse.debug.internal.ui.viewers.update; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; /** * Handles debug events for an event update policy in a viewer. @@ -173,4 +173,14 @@ public abstract class DebugEventHandler { protected synchronized boolean isDisposed() { return fModelProxy == null; } + + protected int indexOf(Object[] list, Object element) { + for (int i = 0; i < list.length; i++) { + if (element.equals(list[i])) { + return i; + } + } + return -1; + } + } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DebugTargetEventHandler.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DebugTargetEventHandler.java index d569f4519..b43a75965 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DebugTargetEventHandler.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DebugTargetEventHandler.java @@ -13,9 +13,9 @@ package org.eclipse.debug.internal.ui.viewers.update; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; /** @@ -60,7 +60,7 @@ public class DebugTargetEventHandler extends DebugEventHandler { } protected void handleTerminate(DebugEvent event) { - fireDelta((IDebugTarget) event.getSource(), IModelDelta.STATE); + fireDelta((IDebugTarget) event.getSource(), IModelDelta.STATE | IModelDelta.UNINSTALL); } private void fireDelta(IDebugTarget target, int flags) { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DebugTargetProxy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DebugTargetProxy.java index e5531c2b7..20dbede55 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DebugTargetProxy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DebugTargetProxy.java @@ -17,8 +17,9 @@ import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.jface.viewers.Viewer; /** * Default model proxy for a debug target. @@ -66,9 +67,9 @@ public class DebugTargetProxy extends EventHandlerModelProxy { } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.viewers.AbstractModelProxy#installed() + * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy#installed(org.eclipse.jface.viewers.Viewer) */ - public void installed() { + public void installed(Viewer viewer) { // select any thread that is already suspended after installation IDebugTarget target = fDebugTarget; if (target != null) { @@ -80,10 +81,10 @@ public class DebugTargetProxy extends EventHandlerModelProxy { IStackFrame frame = thread.getTopStackFrame(); if (frame != null) { ModelDelta delta = new ModelDelta(DebugPlugin.getDefault().getLaunchManager(), IModelDelta.NO_CHANGE); - ModelDelta node = delta.addNode(target.getLaunch(), IModelDelta.NO_CHANGE); - node = node.addNode(target, IModelDelta.NO_CHANGE); - node = node.addNode(thread, IModelDelta.NO_CHANGE | IModelDelta.EXPAND); - node = node.addNode(frame, IModelDelta.NO_CHANGE | IModelDelta.SELECT); + ModelDelta node = delta.addNode(target.getLaunch(), -1, IModelDelta.NO_CHANGE, target.getLaunch().getChildren().length); + node = node.addNode(target, 0, IModelDelta.NO_CHANGE, threads.length); + node = node.addNode(thread, i, IModelDelta.NO_CHANGE | IModelDelta.EXPAND, thread.getStackFrames().length); + node = node.addNode(frame, 0, IModelDelta.NO_CHANGE | IModelDelta.SELECT, 0); fireModelChanged(delta); return; } @@ -91,8 +92,8 @@ public class DebugTargetProxy extends EventHandlerModelProxy { } // expand the target if no suspended thread ModelDelta delta = new ModelDelta(DebugPlugin.getDefault().getLaunchManager(), IModelDelta.NO_CHANGE); - ModelDelta node = delta.addNode(target.getLaunch(), IModelDelta.NO_CHANGE); - node = node.addNode(target, IModelDelta.EXPAND | IModelDelta.SELECT); + ModelDelta node = delta.addNode(target.getLaunch(), -1, IModelDelta.NO_CHANGE, target.getLaunch().getChildren().length); + node = node.addNode(target, 0, IModelDelta.EXPAND | IModelDelta.SELECT, threads.length); fireModelChanged(delta); } catch (DebugException e) { } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultModelProxyFactory.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultModelProxyFactory.java index 18fb82fc8..87e59a95a 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultModelProxyFactory.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultModelProxyFactory.java @@ -20,11 +20,10 @@ import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IWatchExpression; import org.eclipse.debug.internal.ui.memory.provisional.MemoryViewPresentationContext; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxyFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; -import org.eclipse.ui.IWorkbenchPart; public class DefaultModelProxyFactory implements IModelProxyFactoryAdapter { @@ -49,13 +48,9 @@ public class DefaultModelProxyFactory implements IModelProxyFactoryAdapter { if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(id)) { if (element instanceof IExpressionManager) { return new ExpressionManagerModelProxy(); - } if (element instanceof IWatchExpression) { - IWorkbenchPart part = context.getPart(); - if (part == null) { - return null; - } else { - return new DefaultWatchExpressionModelProxy((IWatchExpression)element, part.getSite().getWorkbenchWindow()); - } + } + if (element instanceof IWatchExpression) { + return new DefaultWatchExpressionModelProxy((IWatchExpression)element); } if (element instanceof IExpression) { return new DefaultExpressionModelProxy((IExpression)element); diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultModelSelectionPolicyFactory.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultModelSelectionPolicyFactory.java index fdaf1da30..e6930f3e3 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultModelSelectionPolicyFactory.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultModelSelectionPolicyFactory.java @@ -12,9 +12,9 @@ package org.eclipse.debug.internal.ui.viewers.update; import org.eclipse.debug.core.model.IDebugElement; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelSelectionPolicy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelSelectionPolicyFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicyFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; /** diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultSelectionPolicy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultSelectionPolicy.java index 5cfdac88f..b0fe1d1ad 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultSelectionPolicy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultSelectionPolicy.java @@ -12,8 +12,8 @@ package org.eclipse.debug.internal.ui.viewers.update; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IStackFrame; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelSelectionPolicy; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultVariableViewModelProxy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultVariableViewModelProxy.java index dc449df61..58642c150 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultVariableViewModelProxy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultVariableViewModelProxy.java @@ -59,5 +59,5 @@ public class DefaultVariableViewModelProxy extends EventHandlerModelProxy { } return false; } - + } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultWatchExpressionModelProxy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultWatchExpressionModelProxy.java index 317d34b82..e2fade18f 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultWatchExpressionModelProxy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultWatchExpressionModelProxy.java @@ -10,15 +10,23 @@ *******************************************************************************/ package org.eclipse.debug.internal.ui.viewers.update; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IWatchExpression; +import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.contexts.DebugContextEvent; import org.eclipse.debug.ui.contexts.IDebugContextListener; +import org.eclipse.debug.ui.contexts.IDebugContextService; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.Viewer; import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.progress.UIJob; /** * @since 3.2 @@ -28,21 +36,40 @@ public class DefaultWatchExpressionModelProxy extends DefaultExpressionModelProx private IWorkbenchWindow fWindow; - public DefaultWatchExpressionModelProxy(IWatchExpression expression, IWorkbenchWindow window) { + public DefaultWatchExpressionModelProxy(IWatchExpression expression) { super(expression); - fWindow = window; - DebugUITools.getDebugContextManager().getContextService(window).addDebugContextListener(this); } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy#installed() + * @see org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy#installed(org.eclipse.jface.viewers.Viewer) */ - public void installed() { - super.installed(); - ISelection activeContext = DebugUITools.getDebugContextManager().getContextService(fWindow).getActiveContext(); - if (activeContext != null) { - contextActivated(activeContext); - } + public void installed(final Viewer viewer) { + super.installed(viewer); + UIJob job = new UIJob("install watch expression model proxy") { //$NON-NLS-1$ + public IStatus runInUIThread(IProgressMonitor monitor) { + IWorkbenchWindow[] workbenchWindows = PlatformUI.getWorkbench().getWorkbenchWindows(); + for (int i = 0; i < workbenchWindows.length; i++) { + IWorkbenchWindow window = workbenchWindows[i]; + if (viewer.getControl().getShell().equals(window.getShell())) { + fWindow = window; + break; + } + } + if (fWindow == null) { + fWindow = DebugUIPlugin.getActiveWorkbenchWindow(); + } + IDebugContextService contextService = DebugUITools.getDebugContextManager().getContextService(fWindow); + contextService.addDebugContextListener(DefaultWatchExpressionModelProxy.this); + ISelection activeContext = contextService.getActiveContext(); + if (activeContext != null) { + contextActivated(activeContext); + } + return Status.OK_STATUS; + } + + }; + job.setSystem(true); + job.schedule(); } /* (non-Javadoc) @@ -61,32 +88,28 @@ public class DefaultWatchExpressionModelProxy extends DefaultExpressionModelProx return new DebugEventHandler[]{new ExpressionEventHandler(this)}; } - /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.contexts.provisional.IDebugContextListener#contextEvent(org.eclipse.debug.internal.ui.contexts.provisional.DebugContextEvent) - */ + protected void contextActivated(ISelection selection) { + if (fWindow != null) { + if (selection instanceof IStructuredSelection) { + IDebugElement context = null; + IStructuredSelection ss = (IStructuredSelection)selection; + if (ss.size() < 2) { + Object object = ss.getFirstElement(); + if (object instanceof IDebugElement) { + context= (IDebugElement) object; + } else if (object instanceof ILaunch) { + context= ((ILaunch) object).getDebugTarget(); + } + } + ((IWatchExpression)getExpression()).setExpressionContext(context); + } + } + } + public void debugContextChanged(DebugContextEvent event) { if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) { contextActivated(event.getContext()); } } - - /** - * @param selection - */ - protected void contextActivated(ISelection selection) { - if (selection instanceof IStructuredSelection) { - IDebugElement context = null; - IStructuredSelection ss = (IStructuredSelection)selection; - if (ss.size() < 2) { - Object object = ss.getFirstElement(); - if (object instanceof IDebugElement) { - context= (IDebugElement) object; - } else if (object instanceof ILaunch) { - context= ((ILaunch) object).getDebugTarget(); - } - } - ((IWatchExpression)getExpression()).setExpressionContext(context); - } - } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/EventHandlerModelProxy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/EventHandlerModelProxy.java index 2dec7846c..ab1a133bf 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/EventHandlerModelProxy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/EventHandlerModelProxy.java @@ -18,8 +18,8 @@ import java.util.TimerTask; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; /** * @since 3.2 @@ -47,8 +47,6 @@ public abstract class EventHandlerModelProxy extends AbstractModelProxy implemen */ private DebugEventHandler[] fHandlers = new DebugEventHandler[0]; - private boolean fDisposed = false; - /** * Task used to update an element that resumed for a step or evaluation that * took too long to suspend. @@ -93,7 +91,6 @@ public abstract class EventHandlerModelProxy extends AbstractModelProxy implemen public synchronized void dispose() { super.dispose(); - fDisposed = true; fTimer.cancel(); fTimerTasks.clear(); DebugPlugin.getDefault().removeDebugEventListener(this); @@ -157,10 +154,6 @@ public abstract class EventHandlerModelProxy extends AbstractModelProxy implemen return true; } - protected synchronized boolean isDisposed() { - return fDisposed; - } - /** * Dispatches a create event. * diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ExpressionEventHandler.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ExpressionEventHandler.java index 877bb50a3..9a2f40b06 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ExpressionEventHandler.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ExpressionEventHandler.java @@ -14,10 +14,10 @@ package org.eclipse.debug.internal.ui.viewers.update; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; /** * Event handler for an expression. @@ -48,7 +48,14 @@ public class ExpressionEventHandler extends DebugEventHandler { } } if (expression != null) { - delta.addNode(expression, IModelDelta.CONTENT | IModelDelta.STATE); + int flags = IModelDelta.NO_CHANGE; + if ((event.getDetail() & DebugEvent.STATE) != 0) { + flags = flags | IModelDelta.STATE; + } + if ((event.getDetail() & DebugEvent.CONTENT) != 0) { + flags = flags | IModelDelta.CONTENT; + } + delta.addNode(expression, flags); fireDelta(delta); } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ExpressionManagerModelProxy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ExpressionManagerModelProxy.java index c27c4a88c..487dbec56 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ExpressionManagerModelProxy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ExpressionManagerModelProxy.java @@ -12,12 +12,14 @@ package org.eclipse.debug.internal.ui.viewers.update; import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IExpressionManager; import org.eclipse.debug.core.IExpressionsListener; import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; -import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; +import org.eclipse.jface.viewers.Viewer; public class ExpressionManagerModelProxy extends AbstractModelProxy implements IExpressionsListener { @@ -27,7 +29,21 @@ public class ExpressionManagerModelProxy extends AbstractModelProxy implements I */ public void init(IPresentationContext context) { super.init(context); - DebugPlugin.getDefault().getExpressionManager().addExpressionListener(this); + getExpressionManager().addExpressionListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy#installed(org.eclipse.jface.viewers.Viewer) + */ + public void installed(Viewer viewer) { + updateExpressions(getExpressionManager().getExpressions(), IModelDelta.INSTALL); + } + + /** + * @return + */ + protected IExpressionManager getExpressionManager() { + return DebugPlugin.getDefault().getExpressionManager(); } /* (non-Javadoc) @@ -35,21 +51,21 @@ public class ExpressionManagerModelProxy extends AbstractModelProxy implements I */ public synchronized void dispose() { super.dispose(); - DebugPlugin.getDefault().getExpressionManager().removeExpressionListener(this); + getExpressionManager().removeExpressionListener(this); } /* (non-Javadoc) * @see org.eclipse.debug.core.IExpressionsListener#expressionsAdded(org.eclipse.debug.core.model.IExpression[]) */ public void expressionsAdded(IExpression[] expressions) { - updateExpressions(expressions, IModelDelta.ADDED); + updateExpressions(expressions, IModelDelta.ADDED | IModelDelta.INSTALL); } /* (non-Javadoc) * @see org.eclipse.debug.core.IExpressionsListener#expressionsRemoved(org.eclipse.debug.core.model.IExpression[]) */ public void expressionsRemoved(IExpression[] expressions) { - updateExpressions(expressions, IModelDelta.REMOVED); + updateExpressions(expressions, IModelDelta.REMOVED | IModelDelta.UNINSTALL); } /* (non-Javadoc) @@ -60,7 +76,7 @@ public class ExpressionManagerModelProxy extends AbstractModelProxy implements I } private void updateExpressions(IExpression[] expressions, int flags) { - ModelDelta delta = new ModelDelta(DebugPlugin.getDefault() .getExpressionManager(), IModelDelta.NO_CHANGE); + ModelDelta delta = new ModelDelta(getExpressionManager(), IModelDelta.NO_CHANGE); for (int i = 0; i < expressions.length; i++) { IExpression expression = expressions[i]; delta.addNode(expression, flags); diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/LaunchManagerProxy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/LaunchManagerProxy.java index ed2aaf2ed..13d971d82 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/LaunchManagerProxy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/LaunchManagerProxy.java @@ -10,18 +10,29 @@ *******************************************************************************/ package org.eclipse.debug.internal.ui.viewers.update; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.ILaunchesListener2; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; -import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; +import org.eclipse.jface.viewers.Viewer; public class LaunchManagerProxy extends AbstractModelProxy implements ILaunchesListener2 { private ILaunchManager fLaunchManager; + /** + * Map of each launch to its previous children. When a child is added, + * its model proxy is installed. + */ + private Map fPrevChildren = new HashMap(); /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.AbstractModelProxy#init(org.eclipse.debug.internal.ui.viewers.IPresentationContext) @@ -33,14 +44,12 @@ public class LaunchManagerProxy extends AbstractModelProxy implements ILaunchesL } /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.viewers.AbstractModelProxy#installed() + * @see org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy#installed(org.eclipse.jface.viewers.Viewer) */ - public void installed() { + public void installed(Viewer viewer) { // expand existing launches ILaunch[] launches = fLaunchManager.getLaunches(); - if (launches.length > 0) { - fireDelta(launches, IModelDelta.EXPAND); - } + launchesAdded(launches); } /* (non-Javadoc) @@ -64,6 +73,10 @@ public class LaunchManagerProxy extends AbstractModelProxy implements ILaunchesL */ public void launchesRemoved(ILaunch[] launches) { fireDelta(launches, IModelDelta.REMOVED); + // clear the children cache + for (int i = 0; i < launches.length; i++) { + fPrevChildren.remove(launches[i]); + } } /* (non-Javadoc) @@ -71,6 +84,12 @@ public class LaunchManagerProxy extends AbstractModelProxy implements ILaunchesL */ public void launchesAdded(ILaunch[] launches) { fireDelta(launches, IModelDelta.ADDED | IModelDelta.EXPAND); + // install model proxies + for (int i = 0; i < launches.length; i++) { + ILaunch launch = launches[i]; + fPrevChildren.put(launch, new HashSet()); + } + installModelProxies(launches); } /* (non-Javadoc) @@ -78,6 +97,44 @@ public class LaunchManagerProxy extends AbstractModelProxy implements ILaunchesL */ public void launchesChanged(ILaunch[] launches) { fireDelta(launches, IModelDelta.STATE | IModelDelta.CONTENT); + // install model proxies for new children + installModelProxies(launches); + } + + /** + * Installs model proxies for any new children in the given launches. + * + * @param launches + */ + protected void installModelProxies(ILaunch[] launches) { + boolean changes = false; + ILaunch[] allLaunches = fLaunchManager.getLaunches(); + ModelDelta root = new ModelDelta(fLaunchManager, 0, IModelDelta.NO_CHANGE, allLaunches.length); + for (int i = 0; i < launches.length; i++) { + ILaunch launch = launches[i]; + Object[] children = launch.getChildren(); + ModelDelta launchDelta = root.addNode(launch, indexOf(launch, allLaunches), IModelDelta.EXPAND | IModelDelta.NO_CHANGE, children.length); + Set set = (Set) fPrevChildren.get(launch); + for (int j = 0; j < children.length; j++) { + Object child = children[j]; + if (set.add(child)) { + changes = true; + launchDelta.addNode(child, indexOf(child, children), IModelDelta.INSTALL, -1); + } + } + } + if (changes) { + fireModelChanged(root); + } + } + + protected int indexOf(Object element, Object[] list) { + for (int i = 0; i < list.length; i++) { + if (element == list[i]) { + return i; + } + } + return -1; } protected void fireDelta(ILaunch[] launches, int launchFlags) { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/MemoryBlockProxy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/MemoryBlockProxy.java index 96b5118b8..95c1c56d7 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/MemoryBlockProxy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/MemoryBlockProxy.java @@ -14,8 +14,8 @@ package org.eclipse.debug.internal.ui.viewers.update; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IMemoryBlock; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; public class MemoryBlockProxy extends EventHandlerModelProxy { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/MemoryRetrievalProxy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/MemoryRetrievalProxy.java index 808c0588f..713509587 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/MemoryRetrievalProxy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/MemoryRetrievalProxy.java @@ -17,14 +17,16 @@ import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IMemoryBlockListener; import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IMemoryBlockRetrieval; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; -import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; import org.eclipse.debug.ui.memory.IMemoryRendering; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.Viewer; public class MemoryRetrievalProxy extends AbstractModelProxy implements IMemoryBlockListener { private IMemoryBlockRetrieval fRetrieval; @@ -103,18 +105,14 @@ public class MemoryRetrievalProxy extends AbstractModelProxy implements IMemoryB } } - private IStructuredSelection getCurrentSelection() - { - if (getPresentationContext() == null) - { - return StructuredSelection.EMPTY; + private IStructuredSelection getCurrentSelection() { + Viewer viewer = getViewer(); + if (viewer instanceof StructuredViewer) { + StructuredViewer sv = (StructuredViewer) viewer; + ISelection selection = sv.getSelection(); + if (selection instanceof IStructuredSelection) + return (IStructuredSelection)selection; } - - ISelection selection = getPresentationContext().getPart().getSite().getSelectionProvider().getSelection(); - - if (selection instanceof IStructuredSelection) - return (IStructuredSelection)selection; - return StructuredSelection.EMPTY; } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ProcessProxy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ProcessProxy.java index 2157ad040..9644344ed 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ProcessProxy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ProcessProxy.java @@ -15,8 +15,9 @@ import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.model.IProcess; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +import org.eclipse.jface.viewers.Viewer; public class ProcessProxy extends EventHandlerModelProxy { @@ -28,29 +29,31 @@ public class ProcessProxy extends EventHandlerModelProxy { } protected void handleChange(DebugEvent event) { + fireDelta(IModelDelta.STATE); + } + + protected void handleCreate(DebugEvent event) { + // do nothing - Launch change notification handles this + } + + protected void handleTerminate(DebugEvent event) { + fireDelta(IModelDelta.STATE | IModelDelta.UNINSTALL); + } + + private void fireDelta(int flags) { ModelDelta delta = null; synchronized (ProcessProxy.this) { if (!isDisposed()) { delta = new ModelDelta(DebugPlugin.getDefault().getLaunchManager(), IModelDelta.NO_CHANGE); ModelDelta node = delta; node = node.addNode(fProcess.getLaunch(), IModelDelta.NO_CHANGE); - node.addNode(fProcess, IModelDelta.STATE); + node.addNode(fProcess, flags); } } if (delta != null && !isDisposed()) { fireModelChanged(delta); - } + } } - - protected void handleCreate(DebugEvent event) { - // do nothing - Launch change notification handles this - } - - protected void handleTerminate(DebugEvent event) { - handleChange(event); - } - - }; @@ -77,7 +80,8 @@ public class ProcessProxy extends EventHandlerModelProxy { /* (non-Javadoc) * @see org.eclipse.debug.internal.ui.viewers.AbstractModelProxy#installed() */ - public void installed() { + public void installed(Viewer viewer) { + super.installed(viewer); // select process if in run mode IProcess process = fProcess; if (process != null) { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/StackFrameEventHandler.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/StackFrameEventHandler.java index e0a9b3d9c..e4ead5ee1 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/StackFrameEventHandler.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/StackFrameEventHandler.java @@ -12,9 +12,9 @@ package org.eclipse.debug.internal.ui.viewers.update; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; /** * Default stack frame event handler for the debug view. diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ThreadEventHandler.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ThreadEventHandler.java index dba944eb9..f73b991c9 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ThreadEventHandler.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/ThreadEventHandler.java @@ -18,12 +18,14 @@ import java.util.Set; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; /** * @since 3.2 @@ -162,12 +164,36 @@ public class ThreadEventHandler extends DebugEventHandler { } protected ModelDelta buildRootDelta() { - return new ModelDelta(DebugPlugin.getDefault().getLaunchManager(), IModelDelta.NO_CHANGE); + return new ModelDelta(getLaunchManager(), IModelDelta.NO_CHANGE); + } + + /** + * Returns the launch manager. + * + * @return the launch manager + */ + protected ILaunchManager getLaunchManager() { + return DebugPlugin.getDefault().getLaunchManager(); } + /** + * Adds nodes into the delta up to but not including the given thread. + * + * @param delta root delta for the view (includes viewer input) + * @param thread thread for which path is requested + * @return + */ protected ModelDelta addPathToThread(ModelDelta delta, IThread thread) { - delta = delta.addNode(thread.getLaunch(), IModelDelta.NO_CHANGE); - return delta.addNode(thread.getDebugTarget(), IModelDelta.NO_CHANGE); + ILaunch launch = thread.getLaunch(); + Object[] children = launch.getChildren(); + delta = delta.addNode(launch, indexOf(getLaunchManager().getLaunches(), launch), IModelDelta.NO_CHANGE, children.length); + IDebugTarget debugTarget = thread.getDebugTarget(); + int numThreads = -1; + try { + numThreads = debugTarget.getThreads().length; + } catch (DebugException e) { + } + return delta.addNode(debugTarget, indexOf(children, debugTarget), IModelDelta.NO_CHANGE, numThreads); } private void fireDeltaAndClearTopFrame(IThread thread, int flags) { @@ -192,20 +218,22 @@ public class ThreadEventHandler extends DebugEventHandler { frame = thread.getTopStackFrame(); } catch (DebugException e) { } + int threadIndex = indexOf(thread); + int childCount = childCount(thread); if (isEqual(frame, prev)) { if (frame == null) { if (thread.isSuspended()) { // no frames, but suspended - update & select - node = node.addNode(thread, flags | IModelDelta.STATE | IModelDelta.SELECT); + node = node.addNode(thread, threadIndex, flags | IModelDelta.STATE | IModelDelta.SELECT, childCount); } } else { - node = node.addNode(thread, flags); + node = node.addNode(thread, threadIndex, flags, childCount); } } else { - node = node.addNode(thread, flags | IModelDelta.CONTENT); + node = node.addNode(thread, threadIndex, flags | IModelDelta.CONTENT, childCount); } if (frame != null) { - node.addNode(frame, IModelDelta.STATE | IModelDelta.SELECT); + node.addNode(frame, indexOf(frame), IModelDelta.STATE | IModelDelta.SELECT, childCount(frame)); } synchronized (this) { if (!isDisposed()) { @@ -215,6 +243,54 @@ public class ThreadEventHandler extends DebugEventHandler { fireDelta(delta); } + /** + * Returns the index of the given thread, relative to its parent in the view. + * + * @param thread thread + * @return index of the thread, relative to its parent + */ + protected int indexOf(IThread thread) { + try { + return indexOf(thread.getDebugTarget().getThreads(), thread); + } catch (DebugException e) { + } + return -1; + } + + /** + * Returns the index of the given frame, relative to its parent in the view. + * + * @param frame frame + * @return index of the frame, relative to its thread + */ + protected int indexOf(IStackFrame frame) { + return 0; + } + + /** + * Returns the number of children the given thread has in the view. + * + * @param thread thread + * @return number of children + */ + protected int childCount(IThread thread) { + try { + return thread.getStackFrames().length; + } catch (DebugException e) { + } + return -1; + } + + /** + * Returns the number of children the given frame has in the view. + * + * @param frame frame + * @return child count + */ + protected int childCount(IStackFrame frame) { + return 0; + } + private void fireDeltaUpdatingThread(IThread thread, int flags) { ModelDelta delta = buildRootDelta(); ModelDelta node = addPathToThread(delta, thread); diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/VariablesViewEventHandler.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/VariablesViewEventHandler.java index 4cee189dd..f72a8516b 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/VariablesViewEventHandler.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/VariablesViewEventHandler.java @@ -13,9 +13,9 @@ package org.eclipse.debug.internal.ui.viewers.update; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.ISuspendResume; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; /** * diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementAdapterFactory.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementAdapterFactory.java index b2e4f3137..2b847f314 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementAdapterFactory.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementAdapterFactory.java @@ -43,12 +43,29 @@ import org.eclipse.debug.internal.ui.elements.adapters.ThreadContentAdapter; import org.eclipse.debug.internal.ui.elements.adapters.VariableColumnFactoryAdapter; import org.eclipse.debug.internal.ui.elements.adapters.VariableContentAdapter; import org.eclipse.debug.internal.ui.elements.adapters.VariableLabelAdapter; +import org.eclipse.debug.internal.ui.model.elements.DebugElementLabelProvider; +import org.eclipse.debug.internal.ui.model.elements.DebugTargetContentProvider; +import org.eclipse.debug.internal.ui.model.elements.ExpressionContentProvider; +import org.eclipse.debug.internal.ui.model.elements.ExpressionLabelProvider; +import org.eclipse.debug.internal.ui.model.elements.ExpressionManagerContentProvider; +import org.eclipse.debug.internal.ui.model.elements.LaunchContentProvider; +import org.eclipse.debug.internal.ui.model.elements.LaunchManagerContentProvider; +import org.eclipse.debug.internal.ui.model.elements.StackFrameContentProvider; +import org.eclipse.debug.internal.ui.model.elements.ThreadContentProvider; +import org.eclipse.debug.internal.ui.model.elements.VariableContentProvider; +import org.eclipse.debug.internal.ui.model.elements.VariableEditor; +import org.eclipse.debug.internal.ui.model.elements.VariableLabelProvider; +import org.eclipse.debug.internal.ui.model.elements.VariablesViewElementMementoProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactoryAdapter; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicyFactoryAdapter; 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.IColumnEditorFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxyFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelSelectionPolicyFactoryAdapter; import org.eclipse.debug.internal.ui.viewers.update.DefaultModelProxyFactory; import org.eclipse.debug.internal.ui.viewers.update.DefaultModelSelectionPolicyFactory; import org.eclipse.debug.internal.ui.views.memory.renderings.MemorySegment; @@ -72,6 +89,12 @@ public class DebugElementAdapterFactory implements IAdapterFactory { private static IAsynchronousLabelAdapter fgMemoryBlockLabelAdapter = new MemoryBlockLabelAdapter(); private static IAsynchronousLabelAdapter fgTableRenderingLineLabelAdapter = new MemorySegmentLabelAdapter(); + private static IElementLabelProvider fgLPDebugElement = new DebugElementLabelProvider(); + private static IElementLabelProvider fgLPVariable = new VariableLabelProvider(); + private static IElementLabelProvider fgLPExpression = new ExpressionLabelProvider(); + + private static IElementEditor fgEEVariable = new VariableEditor(); + private static IAsynchronousContentAdapter fgAsyncLaunchManager = new LauchManagerContentAdapter(); private static IAsynchronousContentAdapter fgAsyncLaunch = new LaunchContentAdapter(); private static IAsynchronousContentAdapter fgAsyncTarget = new DebugTargetContentAdapter(); @@ -85,6 +108,17 @@ public class DebugElementAdapterFactory implements IAdapterFactory { private static IAsynchronousContentAdapter fgAsyncMemoryRetrieval = new MemoryRetrievalContentAdapter(); private static IAsynchronousContentAdapter fgAsyncMemoryBlock = new MemoryBlockContentAdapter(); + private static IElementContentProvider fgCPLaunchManger = new LaunchManagerContentProvider(); + private static IElementContentProvider fgCPLaunch = new LaunchContentProvider(); + private static IElementContentProvider fgCPTarget = new DebugTargetContentProvider(); + private static IElementContentProvider fgCPThread = new ThreadContentProvider(); + private static IElementContentProvider fgCPFrame = new StackFrameContentProvider(); + private static IElementContentProvider fgCPVariable = new VariableContentProvider(); + private static IElementContentProvider fgCPExpressionManager = new ExpressionManagerContentProvider(); + private static IElementContentProvider fgCPExpression = new ExpressionContentProvider(); + + private static IElementMementoProvider fgMPFrame = new VariablesViewElementMementoProvider(); + private static IColumnPresentationFactoryAdapter fgVariableColumnFactory = new VariableColumnFactoryAdapter(); @@ -135,6 +169,33 @@ public class DebugElementAdapterFactory implements IAdapterFactory { } } + if (adapterType.equals(IElementContentProvider.class)) { + if (adaptableObject instanceof ILaunchManager) { + return fgCPLaunchManger; + } + if (adaptableObject instanceof ILaunch) { + return fgCPLaunch; + } + if (adaptableObject instanceof IDebugTarget) { + return fgCPTarget; + } + if (adaptableObject instanceof IThread) { + return fgCPThread; + } + if (adaptableObject instanceof IStackFrame) { + return fgCPFrame; + } + if (adaptableObject instanceof IVariable) { + return fgCPVariable; + } + if (adaptableObject instanceof IExpressionManager) { + return fgCPExpressionManager; + } + if (adaptableObject instanceof IExpression) { + return fgCPExpression; + } + } + if (adapterType.equals(IAsynchronousLabelAdapter.class)) { if (adaptableObject instanceof IExpression) { return fgExpressionLabelAdapter; @@ -153,6 +214,16 @@ public class DebugElementAdapterFactory implements IAdapterFactory { return fgDebugLabelAdapter; } + if (adapterType.equals(IElementLabelProvider.class)) { + if (adaptableObject instanceof IVariable) { + return fgLPVariable; + } + if (adaptableObject instanceof IExpression) { + return fgLPExpression; + } + return fgLPDebugElement; + } + if (adapterType.equals(IModelProxyFactoryAdapter.class)) { if (adaptableObject instanceof IDebugTarget || adaptableObject instanceof IProcess || adaptableObject instanceof ILaunchManager || @@ -184,7 +255,20 @@ public class DebugElementAdapterFactory implements IAdapterFactory { if (adaptableObject instanceof IVariable) { return fgVariableColumnFactory; } - } + } + + if (adapterType.equals(IElementMementoProvider.class)) { + if (adaptableObject instanceof IStackFrame) { + return fgMPFrame; + } + } + + if (adapterType.equals(IElementEditor.class)) { + if (adaptableObject instanceof IVariable) { + return fgEEVariable; + } + } + return null; } @@ -193,7 +277,8 @@ public class DebugElementAdapterFactory implements IAdapterFactory { */ public Class[] getAdapterList() { return new Class[] {IWorkbenchAdapter.class, IWorkbenchAdapter2.class, IDeferredWorkbenchAdapter.class, IAsynchronousLabelAdapter.class, IAsynchronousContentAdapter.class, - IModelProxyFactoryAdapter.class, ISourceDisplay.class, IModelSelectionPolicyFactoryAdapter.class, IColumnPresentationFactoryAdapter.class, IColumnEditorFactoryAdapter.class}; + IModelProxyFactoryAdapter.class, ISourceDisplay.class, IModelSelectionPolicyFactoryAdapter.class, IColumnPresentationFactoryAdapter.class, IColumnEditorFactoryAdapter.class, + IElementContentProvider.class, IElementLabelProvider.class, IElementMementoProvider.class, IElementEditor.class}; } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementHelper.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementHelper.java index 5a0721888..27f4f0188 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementHelper.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementHelper.java @@ -14,7 +14,10 @@ import java.util.HashMap; import java.util.Map; import org.eclipse.debug.internal.ui.DelegatingModelPresentation; +import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.IFontProvider; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; @@ -62,6 +65,18 @@ public class DebugElementHelper { return getImageDescriptor(image); } + /** + * Returns an image descriptor for the given debug element. + * + * @param presentation presentation to obtain image from + * @param object object for which an image descriptor is required + * @since 3.3 + */ + public static ImageDescriptor getImageDescriptor(Object object, IDebugModelPresentation presentation) { + Image image = presentation.getImage(object); + return getImageDescriptor(image); + } + public static ImageDescriptor getImageDescriptor(Image image) { if (image != null) { @@ -111,6 +126,30 @@ public class DebugElementHelper { } return null; } + + /** + * Returns the RGB of the foreground color for the given element, or + * <code>null</code> if none. + * + * @param element object for which a foreground color is required + * @param presentation presentation to obtain color from + * @return the RGB of the foreground color for the given element, or + * <code>null</code> if none + * @since 3.3 + */ + public static RGB getForeground(Object element, IDebugModelPresentation presentation) { + Color color = null; + if (presentation instanceof IColorProvider) { + IColorProvider colorProvider = (IColorProvider) presentation; + color = colorProvider.getForeground(element); + } else { + color = getPresentation().getForeground(element); + } + if (color != null) { + return color.getRGB(); + } + return null; + } /** * Returns the RGB of the background color for the given element, or @@ -127,6 +166,30 @@ public class DebugElementHelper { } return null; } + + /** + * Returns the RGB of the background color for the given element, or + * <code>null</code> if none. + * + * @param element object for which a background color is required + * @param presentation presentation to use to retrieve color + * @return the RGB of the background color for the given element, or + * <code>null</code> if none + * @since 3.3 + */ + public static RGB getBackground(Object element, IDebugModelPresentation presentation) { + Color color = null; + if (presentation instanceof IColorProvider) { + IColorProvider colorProvider = (IColorProvider) presentation; + color = colorProvider.getBackground(element); + } else { + color = getPresentation().getBackground(element); + } + if (color != null) { + return color.getRGB(); + } + return null; + } /** * Returns the font data for the given element, or @@ -143,4 +206,28 @@ public class DebugElementHelper { } return null; } + + /** + * Returns the font data for the given element, or + * <code>null</code> if none. + * + * @param element object for which font data is required + * @param presentation presentation to obtain font from + * @return the font data for the given element, or + * <code>null</code> if none + * @since 3.3 + */ + public static FontData getFont(Object element, IDebugModelPresentation presentation) { + Font font = null; + if (presentation instanceof IFontProvider) { + IFontProvider provider = (IFontProvider) presentation; + font = provider.getFont(element); + } else { + font = getPresentation().getFont(element); + } + if (font != null) { + return font.getFontData()[0]; + } + return null; + } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchTreeModel.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchTreeModel.java index f0efde715..13e1d4787 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchTreeModel.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchTreeModel.java @@ -21,9 +21,9 @@ import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.viewers.AsynchronousTreeModel; import org.eclipse.debug.internal.ui.viewers.AsynchronousTreeViewer; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.ui.model.IWorkbenchAdapter; import org.eclipse.ui.progress.IDeferredWorkbenchAdapter; diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchView.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchView.java index c6a3cc5fe..d53162a62 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchView.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchView.java @@ -33,7 +33,6 @@ import org.eclipse.debug.internal.ui.DelegatingModelPresentation; import org.eclipse.debug.internal.ui.IDebugHelpContextIds; import org.eclipse.debug.internal.ui.actions.AddToFavoritesAction; import org.eclipse.debug.internal.ui.actions.EditLaunchConfigurationAction; -import org.eclipse.debug.internal.ui.actions.FindElementAction; import org.eclipse.debug.internal.ui.commands.actions.DebugCommandAction; import org.eclipse.debug.internal.ui.commands.actions.DisconnectCommandAction; import org.eclipse.debug.internal.ui.commands.actions.DropToFrameCommandAction; @@ -50,11 +49,15 @@ import org.eclipse.debug.internal.ui.commands.actions.ToggleStepFiltersAction; import org.eclipse.debug.internal.ui.sourcelookup.EditSourceLookupPathAction; import org.eclipse.debug.internal.ui.sourcelookup.LookupSourceAction; import org.eclipse.debug.internal.ui.viewers.AsynchronousTreeViewer; -import org.eclipse.debug.internal.ui.viewers.PresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDeltaVisitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; +import org.eclipse.debug.internal.ui.views.DebugModelPresentationContext; import org.eclipse.debug.internal.ui.views.DebugUIViewsMessages; import org.eclipse.debug.ui.AbstractDebugView; import org.eclipse.debug.ui.DebugUITools; -import org.eclipse.debug.ui.IDebugEditorPresentation; import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.contexts.AbstractDebugContextProvider; @@ -129,26 +132,48 @@ public class LaunchView extends AbstractDebugView implements ISelectionChangedLi private boolean fIsActive = true; /** - * Editor presentation or <code>null</code> if none + * Model presentation or <code>null</code> if none */ - private IDebugEditorPresentation fEditorPresentation = null; + private IDebugModelPresentation fPresentation = null; private EditLaunchConfigurationAction fEditConfigAction = null; private AddToFavoritesAction fAddToFavoritesAction = null; private EditSourceLookupPathAction fEditSourceAction = null; private LookupSourceAction fLookupAction = null; - class ContextProvider extends AbstractDebugContextProvider { + class ContextProvider extends AbstractDebugContextProvider implements IModelChangedListener { - public ContextProvider() { + private ISelection fContext = null; + private TreeModelViewer fViewer = null; + private Visitor fVisitor = new Visitor(); + + class Visitor implements IModelDeltaVisitor { + public boolean visit(IModelDelta delta, int depth) { + Object element = delta.getElement(); + if ((delta.getFlags() & IModelDelta.STATE) > 0) { + if ((delta.getFlags() & (IModelDelta.CONTENT | IModelDelta.SELECT)) == 0) { + // state change without content/select - possible state change of active context + possibleChange(element, DebugContextEvent.STATE); + } + } else if ((delta.getFlags() & IModelDelta.CONTENT) > 0) { + if ((delta.getFlags() & IModelDelta.SELECT) == 0) { + // content change without select > possible activation + possibleChange(element, DebugContextEvent.ACTIVATED); + } + } + return true; + } + } + + public ContextProvider(TreeModelViewer viewer) { super(LaunchView.this); - // TODO Auto-generated constructor stub + fViewer = viewer; + fViewer.addModelChangedListener(this); } - - private ISelection fContext = null; protected void dispose() { fContext = null; + fViewer.removeModelChangedListener(this); } /* (non-Javadoc) @@ -165,7 +190,7 @@ public class LaunchView extends AbstractDebugView implements ISelectionChangedLi fire(new DebugContextEvent(this, selection, DebugContextEvent.ACTIVATED)); } - protected void possibleContextChange(Object element, int type) { + protected void possibleChange(Object element, int type) { synchronized (this) { if (fContext instanceof IStructuredSelection) { IStructuredSelection ss = (IStructuredSelection) fContext; @@ -176,7 +201,7 @@ public class LaunchView extends AbstractDebugView implements ISelectionChangedLi return; } } - DebugContextEvent event = new DebugContextEvent(ContextProvider.this, fContext, type); + DebugContextEvent event = new DebugContextEvent(this, fContext, type); if (getControl().getDisplay().getThread() == Thread.currentThread()) { fire(event); } else { @@ -186,19 +211,25 @@ public class LaunchView extends AbstractDebugView implements ISelectionChangedLi fire(finalEvent); return Status.OK_STATUS; } - - }; + }; job.setSystem(true); job.schedule(); } } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener#modelChanged(org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta) + */ + public void modelChanged(IModelDelta delta, IModelProxy proxy) { + delta.accept(fVisitor); + } } /** * Context provider */ - private ContextProvider fProvider = new ContextProvider(); + private ContextProvider fProvider; /* (non-Javadoc) * @see org.eclipse.debug.ui.AbstractDebugView#getHelpContextId() @@ -216,7 +247,7 @@ public class LaunchView extends AbstractDebugView implements ISelectionChangedLi fAddToFavoritesAction = new AddToFavoritesAction(); fEditSourceAction = new EditSourceLookupPathAction(this); fLookupAction = new LookupSourceAction(this); - setAction(FIND_ACTION, new FindElementAction(this, (AsynchronousTreeViewer) getViewer())); + //setAction(FIND_ACTION, new FindElementAction(this, (AsynchronousTreeViewer) getViewer())); // TODO: addCapabilityAction(new TerminateCommandAction(), TERMINATE); addCapabilityAction(new DisconnectCommandAction(), DISCONNECT); @@ -258,8 +289,10 @@ public class LaunchView extends AbstractDebugView implements ISelectionChangedLi * @see org.eclipse.debug.ui.AbstractDebugView#createViewer(org.eclipse.swt.widgets.Composite) */ protected Viewer createViewer(Composite parent) { - AsynchronousTreeViewer viewer = new LaunchViewer(parent, this); - viewer.setContext(new PresentationContext(this)); + fPresentation = new DelegatingModelPresentation(); + TreeModelViewer viewer = new TreeModelViewer(parent, + SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.VIRTUAL, + new DebugModelPresentationContext(IDebugUIConstants.ID_DEBUG_VIEW, fPresentation)); viewer.addSelectionChangedListener(this); viewer.getControl().addKeyListener(new KeyAdapter() { @@ -269,12 +302,11 @@ public class LaunchView extends AbstractDebugView implements ISelectionChangedLi } } }); - final DelegatingModelPresentation presentation = new DelegatingModelPresentation(); - fEditorPresentation = presentation; // add my viewer as a selection provider, so selective re-launch works getSite().setSelectionProvider(viewer); viewer.setInput(DebugPlugin.getDefault().getLaunchManager()); //setEventHandler(new LaunchViewEventHandler(this)); + fProvider = new ContextProvider(viewer); DebugUITools.getDebugContextManager().getContextService(getSite().getWorkbenchWindow()).addDebugContextProvider(fProvider); return viewer; } @@ -459,7 +491,7 @@ public class LaunchView extends AbstractDebugView implements ISelectionChangedLi } protected void possibleContextChange(Object element, int type) { - fProvider.possibleContextChange(element, type); + // TODO: remove } /* (non-Javadoc) @@ -526,7 +558,7 @@ public class LaunchView extends AbstractDebugView implements ISelectionChangedLi * @see org.eclipse.debug.ui.IDebugView#getPresentation(java.lang.String) */ public IDebugModelPresentation getPresentation(String id) { - return ((DelegatingModelPresentation)fEditorPresentation).getPresentation(id); + return ((DelegatingModelPresentation)fPresentation).getPresentation(id); } /* (non-Javadoc) @@ -536,7 +568,7 @@ public class LaunchView extends AbstractDebugView implements ISelectionChangedLi menu.add(new Separator(IDebugUIConstants.EMPTY_EDIT_GROUP)); menu.add(new Separator(IDebugUIConstants.EDIT_GROUP)); - menu.add(getAction(FIND_ACTION)); + //menu.add(getAction(FIND_ACTION)); TODO: menu.add(new Separator(IDebugUIConstants.EMPTY_STEP_GROUP)); menu.add(new Separator(IDebugUIConstants.STEP_GROUP)); menu.add(new GroupMarker(IDebugUIConstants.STEP_INTO_GROUP)); diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchViewUpdatePolicy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchViewUpdatePolicy.java index b640be83d..e35dcf65a 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchViewUpdatePolicy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchViewUpdatePolicy.java @@ -12,7 +12,7 @@ package org.eclipse.debug.internal.ui.views.launch; import org.eclipse.debug.internal.ui.viewers.AsynchronousTreeViewer; import org.eclipse.debug.internal.ui.viewers.TreeUpdatePolicy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.ui.contexts.DebugContextEvent; /** diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/ToggleShowColumnsAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/ToggleShowColumnsAction.java index efae55c12..7dee94008 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/ToggleShowColumnsAction.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/ToggleShowColumnsAction.java @@ -13,7 +13,7 @@ package org.eclipse.debug.internal.ui.views.variables; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IDebugHelpContextIds; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; -import org.eclipse.debug.internal.ui.viewers.AsynchronousTreeViewer; +import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; @@ -29,9 +29,9 @@ import org.eclipse.ui.texteditor.IUpdate; */ public class ToggleShowColumnsAction extends Action implements IUpdate { - private AsynchronousTreeViewer fViewer; + private TreeModelViewer fViewer; - public ToggleShowColumnsAction(AsynchronousTreeViewer viewew) { + public ToggleShowColumnsAction(TreeModelViewer viewew) { super(VariablesViewMessages.ToggleShowColumnsAction_0, IAction.AS_CHECK_BOX); fViewer = viewew; setToolTipText(VariablesViewMessages.ToggleShowColumnsAction_1); diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/VariablesView.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/VariablesView.java index befa47f69..7c93ff98e 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/VariablesView.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/VariablesView.java @@ -18,14 +18,11 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; -import java.util.HashMap; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.ResourceBundle; import org.eclipse.core.commands.operations.IUndoContext; -import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -46,16 +43,19 @@ import org.eclipse.debug.internal.ui.LazyModelPresentation; import org.eclipse.debug.internal.ui.VariablesViewModelPresentation; import org.eclipse.debug.internal.ui.actions.CollapseAllAction; import org.eclipse.debug.internal.ui.actions.ConfigureColumnsAction; -import org.eclipse.debug.internal.ui.actions.FindElementAction; import org.eclipse.debug.internal.ui.actions.variables.AssignValueAction; import org.eclipse.debug.internal.ui.actions.variables.ChangeVariableValueAction; import org.eclipse.debug.internal.ui.actions.variables.ShowTypesAction; import org.eclipse.debug.internal.ui.actions.variables.ToggleDetailPaneAction; import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; -import org.eclipse.debug.internal.ui.viewers.AsynchronousTreeViewer; -import org.eclipse.debug.internal.ui.viewers.PresentationContext; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; -import org.eclipse.debug.internal.ui.views.AbstractViewerState; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDeltaVisitor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; +import org.eclipse.debug.internal.ui.views.DebugModelPresentationContext; import org.eclipse.debug.internal.ui.views.IDebugExceptionHandler; import org.eclipse.debug.ui.AbstractDebugView; import org.eclipse.debug.ui.DebugUITools; @@ -63,6 +63,7 @@ import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.IDebugView; import org.eclipse.debug.ui.IValueDetailListener; +import org.eclipse.debug.ui.commands.IStatusMonitor; import org.eclipse.debug.ui.contexts.DebugContextEvent; import org.eclipse.debug.ui.contexts.IDebugContextListener; import org.eclipse.jface.action.Action; @@ -100,6 +101,7 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; @@ -132,6 +134,7 @@ import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.operations.OperationHistoryActionHandler; import org.eclipse.ui.operations.RedoActionHandler; import org.eclipse.ui.operations.UndoActionHandler; +import org.eclipse.ui.progress.UIJob; import org.eclipse.ui.progress.WorkbenchJob; import org.eclipse.ui.texteditor.FindReplaceAction; import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds; @@ -146,9 +149,9 @@ import com.ibm.icu.text.MessageFormat; * This view shows variables and their values for a particular stack frame */ public class VariablesView extends AbstractDebugView implements IDebugContextListener, - IPropertyChangeListener, - IDebugExceptionHandler, - IPerspectiveListener { + IPropertyChangeListener, IDebugExceptionHandler, + IPerspectiveListener, IModelChangedListener, + IViewerUpdateListener { /** * Internal interface for a cursor listener. I.e. aggregation @@ -157,44 +160,6 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis */ interface ICursorListener extends MouseListener, KeyListener { } - - /** - * Most recently used variant with capped size that only counts - * {@linkplain #put(Object, Object) put} as access. This is implemented by always removing an - * element before it gets put back. - * - * @since 3.2 - */ - private static final class MRUMap extends LinkedHashMap { - private static final long serialVersionUID= 1L; - private final int fMaxSize; - - /** - * Creates a new <code>MRUMap</code> with the given size. - * - * @param maxSize the maximum size of the cache, must be > 0 - */ - public MRUMap(int maxSize) { - Assert.isLegal(maxSize > 0); - fMaxSize= maxSize; - } - - /* - * @see java.util.HashMap#put(java.lang.Object, java.lang.Object) - */ - public Object put(Object key, Object value) { - Object object= remove(key); - super.put(key, value); - return object; - } - - /* - * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) - */ - protected boolean removeEldestEntry(java.util.Map.Entry eldest) { - return size() > fMaxSize; - } - } /** * The selection provider for the variables view changes depending on whether @@ -263,14 +228,22 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis } } public void run() { - getFindAction().run(); + IAction findAction = getFindAction(); + if (findAction != null) { + findAction.run(); + } } /* (non-Javadoc) * @see org.eclipse.ui.texteditor.IUpdate#update() */ public void update() { - setEnabled(getFindAction().isEnabled()); + IAction findAction = getFindAction(); + if (findAction != null) { + setEnabled(findAction.isEnabled()); + } else { + setEnabled(false); + } } } @@ -314,6 +287,9 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis val = null; } if (val != null && !monitor.isCanceled()) { + if (monitor.isCanceled()) { + break; + } getModelPresentation().computeDetail(val, this); synchronized (this) { try { @@ -426,21 +402,6 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis private List fSelectionActions = new ArrayList(3); /** - * An MRU cache of stack frame hash codes to <code>ViewerState</code>s. - * Used to restore the expanded state of the variables view on - * re-selection of the same stack frame. The cache is limited - * to twenty entries. - */ - private HashMap fSelectionStates = new MRUMap(20); - - /** - * The last known viewer state. Used to initialize the expansion/selection - * in the variables view when there is no state to go on for the - * current stack frame being displayed. - */ - private AbstractViewerState fLastState = null; - - /** * Remembers which viewer (tree viewer or details viewer) had focus, so we * can reset the focus properly when re-activated. */ @@ -467,6 +428,13 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis public static final String LOGICAL_STRUCTURE_TYPE_PREFIX = "VAR_LS_"; //$NON-NLS-1$ /** + * Presentation context property. + * TODO: make API + * @since 3.3 + */ + public static final String PRESENTATION_SHOW_LOGICAL_STRUCTURES = "PRESENTATION_SHOW_LOGICAL_STRUCTURES"; //$NON-NLS-1$ + + /** * the preference name for the view part of the sash form * @since 3.2 */ @@ -503,9 +471,57 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis private final PositionLabelValue fColumnLabel= new PositionLabelValue(); /** The arguments for the position label pattern. */ private final Object[] fPositionLabelPatternArguments= new Object[] { fLineLabel, fColumnLabel }; - /** Whether logical structures are showing */ - private boolean fShowLogical; + /** + * Visits deltas to determine if details should be displayed + */ + class Visitor implements IModelDeltaVisitor { + /** + * Whether to trigger details display. + * + * @since 3.3 + */ + private boolean fTriggerDetails = false; + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelDeltaVisitor#visit(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta, int) + */ + public boolean visit(IModelDelta delta, int depth) { + if ((delta.getFlags() & IModelDelta.CONTENT) > 0) { + fTriggerDetails = true; + return false; + } + return true; + } + + public void reset() { + fTriggerDetails = false; + } + + public boolean isTriggerDetails() { + return fTriggerDetails; + } + + } + /** + * Delta visitor + */ + private Visitor fVisitor = new Visitor(); + + /** + * Job to update details in the UI thread. + */ + private Job fTriggerDetailsJob = new UIJob("trigger details") { //$NON-NLS-1$ + + public IStatus runInUIThread(IProgressMonitor monitor) { + if (monitor.isCanceled()) { + return Status.CANCEL_STATUS; + } + populateDetailPane(); + return Status.OK_STATUS; + } + + }; + /** * Remove myself as a selection listener * and preference change listener. @@ -518,15 +534,12 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis getSite().getWorkbenchWindow().removePerspectiveListener(this); DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this); JFaceResources.getFontRegistry().removeListener(this); - Viewer viewer = getViewer(); + TreeModelViewer viewer = getVariablesViewer(); if (viewer != null) { getDetailDocument().removeDocumentListener(getDetailDocumentListener()); - if (viewer instanceof AsynchronousTreeViewer) { - AsynchronousTreeViewer asyncTreeViewer = (AsynchronousTreeViewer) viewer; - asyncTreeViewer.dispose(); - } + viewer.removeModelChangedListener(this); + viewer.removeViewerUpdateListener(this); } - fSelectionStates.clear(); super.dispose(); } @@ -549,79 +562,15 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis if (current != null && current.equals(context)) { return; - } - - if (current != null) { - // save state - AbstractViewerState state = getViewerState(); - cacheViewerState(current, state); - fLastState = (AbstractViewerState) state.clone(); - } + } if (context instanceof IDebugElement) { setDebugModel(((IDebugElement)context).getModelIdentifier()); } showViewer(); getViewer().setInput(context); - restoreState(); } - - /** - * Caches the given viewer state for the given viewer input. - * - * @param input viewer input - * @param state viewer state - */ - protected void cacheViewerState(Object input, AbstractViewerState state) { - // generate a key for the input based on its hash code, we don't - // want to maintain reference real model objects preventing GCs. - fSelectionStates.put(generateKey(input), state); - } - - /** - * Generate a key for an input object. - * - * @param input - * @return key - */ - protected Object generateKey(Object input) { - return new Integer(input.hashCode()); - } - - /** - * Returns the cached viewer state for the given viewer input or - * <code>null</code> if none. - * - * @param input viewer input - * @return viewer state or <code>null</code> - */ - protected AbstractViewerState getCachedViewerState(Object input) { - return (AbstractViewerState) fSelectionStates.get(generateKey(input)); - } - - /** - * Restores the state of the viewer - */ - protected void restoreState() { - VariablesViewer viewer = (VariablesViewer) getViewer(); - if (viewer != null) { - Object context = viewer.getInput(); - if (context != null) { - AbstractViewerState state = getCachedViewerState(context); - if (state == null) { - // attempt to restore selection/expansion based on last - // frame - if (fLastState != null) { - state = fLastState; - } - } - if (state != null) { - state.restoreState(viewer); - } - } - } - } - + /** * Configures the details viewer for the debug model * currently being displayed @@ -671,8 +620,8 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis * @see org.eclipse.debug.ui.AbstractDebugView#createViewer(Composite) */ public Viewer createViewer(Composite parent) { - VariablesViewer variablesViewer = (VariablesViewer) createTreeViewer(parent); - variablesViewer.setContext(new PresentationContext(this)); + fTriggerDetailsJob.setSystem(true); + TreeModelViewer variablesViewer = createTreeViewer(parent); variablesViewer.getPresentationContext().addPropertyChangeListener( new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { @@ -699,6 +648,8 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis if (memento != null) { variablesViewer.initState(memento); } + variablesViewer.addModelChangedListener(this); + variablesViewer.addViewerUpdateListener(this); return variablesViewer; } @@ -796,7 +747,7 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis /** * Create and return the main tree viewer that displays variable. */ - protected Viewer createTreeViewer(Composite parent) { + protected TreeModelViewer createTreeViewer(Composite parent) { fModelPresentation = new VariablesViewModelPresentation(); DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this); JFaceResources.getFontRegistry().addListener(this); @@ -805,7 +756,9 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis fSashForm = new SashForm(parent, SWT.NONE); // add tree viewer - final VariablesViewer variablesViewer = createVariablesViewer(fSashForm); + int style = getViewerStyle(); + final TreeModelViewer variablesViewer = new TreeModelViewer(fSashForm, style, + new DebugModelPresentationContext(getPresentationContextId(), fModelPresentation)); variablesViewer.getControl().addFocusListener(new FocusAdapter() { /* (non-Javadoc) * @see org.eclipse.swt.events.FocusListener#focusGained(FocusEvent) @@ -826,15 +779,23 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis DebugUITools.getDebugContextManager().getContextService(getSite().getWorkbenchWindow()).addDebugContextListener(this); return variablesViewer; } + + /** + * Returns the presentation context id for this view. + * + * @return context id + */ + protected String getPresentationContextId() { + return IDebugUIConstants.ID_VARIABLE_VIEW; + } /** - * Creates and returns a variables viewer in the given composite. + * Returns the style bits for the viewer. * - * @param parent - * @return variables viewer + * @return SWT style */ - protected VariablesViewer createVariablesViewer(Composite parent) { - return new VariablesViewer(parent, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.VIRTUAL | SWT.FULL_SELECTION, this); + protected int getViewerStyle() { + return SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.VIRTUAL | SWT.FULL_SELECTION; } /** @@ -1006,7 +967,7 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis action = new ToggleLogicalStructureAction(this); setAction("ToggleContentProviders", action); //$NON-NLS-1$ - action = new CollapseAllAction((AsynchronousTreeViewer)getViewer()); + action = new CollapseAllAction((TreeViewer)getViewer()); setAction("CollapseAll", action); //$NON-NLS-1$ action = new ChangeVariableValueAction(this); @@ -1045,8 +1006,9 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis textAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE); setAction(ActionFactory.PASTE.getId(), textAction); - action= new FindElementAction(this, getVariablesViewer()); - setAction(FIND_ELEMENT, action); + //TODO: + //action= new FindElementAction(this, getVariablesViewer()); + //setAction(FIND_ELEMENT, action); // TODO: Still using "old" resource access ResourceBundle bundle= ResourceBundle.getBundle("org.eclipse.debug.internal.ui.views.variables.VariablesViewResourceBundleMessages"); //$NON-NLS-1$ @@ -1119,7 +1081,7 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis return null; } - private void createOrientationActions(VariablesViewer viewer) { + private void createOrientationActions(TreeModelViewer viewer) { IActionBars actionBars = getViewSite().getActionBars(); IMenuManager viewMenu = actionBars.getMenuManager(); @@ -1184,7 +1146,8 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis menu.add(new Separator(IDebugUIConstants.EMPTY_VARIABLE_GROUP)); menu.add(new Separator(IDebugUIConstants.VARIABLE_GROUP)); - menu.add(getAction(FIND_ELEMENT)); + // TODO: + //menu.add(getAction(FIND_ELEMENT)); menu.add(getAction("ChangeVariableValue")); //$NON-NLS-1$ IAction action = new AvailableLogicalStructuresAction(this); if (action.isEnabled()) { @@ -1270,9 +1233,12 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis if (fDetailsJob != null) { fDetailsJob.cancel(); } - fDetailsJob = new DetailJob(selection); - setDetails(""); //$NON-NLS-1$ - fDetailsJob.schedule(); + if (selection.isEmpty()) { + setDetails(""); //$NON-NLS-1$ + } else { + fDetailsJob = new DetailJob(selection); + fDetailsJob.schedule(); + } } } @@ -1456,15 +1422,12 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis return fSelectionProvider; } - /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.contexts.provisional.IDebugContextListener#contextEvent(org.eclipse.debug.internal.ui.contexts.provisional.DebugContextEvent) - */ public void debugContextChanged(DebugContextEvent event) { if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) { contextActivated(event.getContext()); } } - + protected void contextActivated(ISelection selection) { if (!isAvailable() || !isVisible()) { return; @@ -1479,7 +1442,7 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis updateAction(FIND_ELEMENT); updateAction(FIND_ACTION); } - + /** * Delegate to the <code>DOUBLE_CLICK_ACTION</code>, * if any. @@ -1553,18 +1516,23 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis return isAvailable(); } + protected IPresentationContext getPresentationContext() { + return getVariablesViewer().getPresentationContext(); + } + /** * Sets whether logical structures are being displayed */ public void setShowLogicalStructure(boolean flag) { - fShowLogical = flag; + getPresentationContext().setProperty(PRESENTATION_SHOW_LOGICAL_STRUCTURES, Boolean.valueOf(flag)); } /** * Returns whether logical structures are being displayed */ public boolean isShowLogicalStructure() { - return fShowLogical; + Boolean show = (Boolean) getPresentationContext().getProperty(PRESENTATION_SHOW_LOGICAL_STRUCTURES); + return show != null && show.booleanValue(); } /** @@ -1595,18 +1563,9 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis ISelection selection = DebugUITools.getDebugContextManager().getContextService(getSite().getWorkbenchWindow()).getActiveContext(); contextActivated(selection); } - - /** - * Returns the memento of the expanded and selected items in the viewer. - * - * @return the memento of the expanded and selected items in the viewer - */ - protected AbstractViewerState getViewerState() { - return new ViewerState(getVariablesViewer()); - } - protected VariablesViewer getVariablesViewer() { - return (VariablesViewer) getViewer(); + protected TreeModelViewer getVariablesViewer() { + return (TreeModelViewer) getViewer(); } /** @@ -1697,5 +1656,52 @@ public class VariablesView extends AbstractDebugView implements IDebugContextLis setLastSashWeights(DEFAULT_SASH_WEIGHTS); fSashForm.setWeights(DEFAULT_SASH_WEIGHTS); } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener#modelChanged(org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta) + */ + public void modelChanged(IModelDelta delta, IModelProxy proxy) { + fVisitor.reset(); + delta.accept(fVisitor); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IViewerUpdateListener#updateComplete(org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor) + */ + public void updateComplete(IStatusMonitor update) { + IStatus status = update.getStatus(); + if (!update.isCanceled()) { + if (status != null && status.getCode() != IStatus.OK) { + showMessage(status.getMessage()); + } else { + showViewer(); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IViewerUpdateListener#updateStarted(org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor) + */ + public void updateStarted(IStatusMonitor update) { + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IViewerUpdateListener#viewerUpdatesBegin() + */ + public synchronized void viewerUpdatesBegin() { + fTriggerDetailsJob.cancel(); + if (fDetailsJob != null) { + fDetailsJob.cancel(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IViewerUpdateListener#viewerUpdatesComplete() + */ + public synchronized void viewerUpdatesComplete() { + if (fVisitor.isTriggerDetails()) { + fTriggerDetailsJob.schedule(); + } } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/VariablesViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/VariablesViewer.java deleted file mode 100644 index 75ba988ad..000000000 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/variables/VariablesViewer.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2006 IBM Corporation 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: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.debug.internal.ui.views.variables; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.debug.internal.ui.viewers.AsynchronousTreeViewer; -import org.eclipse.debug.ui.commands.IStatusMonitor; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.progress.UIJob; - -/** - * @since 3.2 - * - */ -public class VariablesViewer extends AsynchronousTreeViewer{ - - private VariablesView fView; - - private UIJob fRestoreJob = new UIJob("restore viewer state") { //$NON-NLS-1$ - public IStatus runInUIThread(IProgressMonitor monitor) { - fView.restoreState(); - return Status.OK_STATUS; - } - }; - - public VariablesViewer(Composite parent, int style, VariablesView view) { - super(parent, style); - fView = view; - fRestoreJob.setSystem(true); - } - - protected void updateComplete(IStatusMonitor update) { - if (fView != null && !hasPendingUpdates()) { - fRestoreJob.schedule(); - fView.populateDetailPane(); - } - } - - /* (non-Javadoc) - * @see org.eclipse.debug.internal.ui.treeviewer.AsynchronousTreeViewer#handlePresentationFailure(org.eclipse.debug.internal.ui.treeviewer.IPresentationRequestMonitor, org.eclipse.core.runtime.IStatus) - */ - protected void handlePresentationFailure(IStatusMonitor update, IStatus status) { - fView.showMessage(status.getMessage()); - } - -} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/InspectPopupDialog.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/InspectPopupDialog.java index 308b5b90f..87b7f99f2 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/InspectPopupDialog.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/InspectPopupDialog.java @@ -11,11 +11,10 @@ package org.eclipse.debug.ui; -import java.util.Iterator; import java.util.List; -import java.util.Map; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IExpression; @@ -23,16 +22,15 @@ import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.core.model.IVariable; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.VariablesViewModelPresentation; -import org.eclipse.debug.internal.ui.viewers.PresentationContext; -import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.model.elements.ElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; import org.eclipse.debug.internal.ui.views.DebugUIViewsMessages; import org.eclipse.debug.internal.ui.views.variables.IndexedVariablePartition; import org.eclipse.debug.internal.ui.views.variables.VariablesView; -import org.eclipse.debug.internal.ui.views.variables.VariablesViewer; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.TreePath; -import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; @@ -72,7 +70,7 @@ public class InspectPopupDialog extends DebugPopup { private static final int MIN_HEIGHT = 200; - private VariablesViewer fVariablesViewer; + private TreeModelViewer fViewer; private IDebugModelPresentation fModelPresentation; @@ -112,23 +110,18 @@ public class InspectPopupDialog extends DebugPopup { fSashForm.setLayoutData(new GridData(GridData.FILL_BOTH)); VariablesView view = getViewToEmulate(); - - fVariablesViewer = new VariablesViewer(fSashForm, SWT.NO_TRIM | SWT.VIRTUAL, null); - IPresentationContext context; if (view == null) { context = new PresentationContext(IDebugUIConstants.ID_VARIABLE_VIEW); } else { - context = new PresentationContext(view); + context = ((TreeModelViewer)view.getViewer()).getPresentationContext(); } - fVariablesViewer.setContext(context); + fViewer = new TreeModelViewer(fSashForm, SWT.NO_TRIM | SWT.VIRTUAL, context); fModelPresentation = new VariablesViewModelPresentation(); - fVariablesViewer.setLabelProvider(fModelPresentation); - fValueDisplay = new StyledText(fSashForm, SWT.NO_TRIM | SWT.WRAP | SWT.V_SCROLL); fValueDisplay.setEditable(false); - fTree = fVariablesViewer.getTree(); + fTree = fViewer.getTree(); fTree.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { try { @@ -165,41 +158,44 @@ public class InspectPopupDialog extends DebugPopup { // sashForm.setWeights(getInitialSashWeights()); fSashForm.setWeights(DEFAULT_SASH_WEIGHTS); - fVariablesViewer.getContentProvider(); + fViewer.getContentProvider(); if (view != null) { StructuredViewer structuredViewer = (StructuredViewer) view.getViewer(); if (structuredViewer != null) { ViewerFilter[] filters = structuredViewer.getFilters(); for (int i = 0; i < filters.length; i++) { - fVariablesViewer.addFilter(filters[i]); + fViewer.addFilter(filters[i]); } } - - Map map = view.getPresentationAttributes(fExpression.getModelIdentifier()); - Iterator iterator = map.keySet().iterator(); - while (iterator.hasNext()) { - String key = (String) iterator.next(); - fModelPresentation.setAttribute(key, map.get(key)); - } } TreeRoot treeRoot = new TreeRoot(); - fVariablesViewer.setInput(treeRoot); - fVariablesViewer.expand(new TreeSelection(new TreePath(new Object[] {treeRoot, fExpression}))); + fViewer.setInput(treeRoot); + fViewer.expandToLevel(new TreePath(new Object[] {fExpression}), 1); return fTree; } - private class TreeRoot extends AsynchronousContentAdapter { - protected Object[] getChildren(Object parent, IPresentationContext context) throws CoreException { - return new Object[] { fExpression }; - } - protected boolean hasChildren(Object element, IPresentationContext context) throws CoreException { - return true; - } - protected boolean supportsPartId(String id) { - return true; - } + private class TreeRoot extends ElementContentProvider { + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected int getChildCount(Object element, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return 1; + } + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext) + */ + protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IProgressMonitor monitor) throws CoreException { + return new Object[] { fExpression }; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#supportsContextId(java.lang.String) + */ + protected boolean supportsContextId(String id) { + return true; + } } private void updateValueDisplay(IValue val) { @@ -242,9 +238,6 @@ public class InspectPopupDialog extends DebugPopup { * @see org.eclipse.debug.ui.DebugPopup#close() */ public boolean close() { - if(fVariablesViewer != null) { - fVariablesViewer.dispose(); - } if(fModelPresentation != null) { fModelPresentation.dispose(); } |