diff options
author | Pawel Piech | 2012-03-09 23:11:22 +0000 |
---|---|---|
committer | Pawel Piech | 2012-03-09 23:11:22 +0000 |
commit | 64678065cd9fed43d2a1141912ece7672ca192c6 (patch) | |
tree | 165ce61655cf40e327456742db25b973cb8defd6 /org.eclipse.debug.examples.ui | |
parent | c98ef3633d90d05ac5a82c928a9e20cd46435f3f (diff) | |
download | eclipse.platform.debug-64678065cd9fed43d2a1141912ece7672ca192c6.tar.gz eclipse.platform.debug-64678065cd9fed43d2a1141912ece7672ca192c6.tar.xz eclipse.platform.debug-64678065cd9fed43d2a1141912ece7672ca192c6.zip |
Bug 344023 - [var] Need a way to override Find action of Variablesv20120309-2311
view and its derived classes
Standardized action IDs used in variables views.
Diffstat (limited to 'org.eclipse.debug.examples.ui')
5 files changed, 382 insertions, 4 deletions
diff --git a/org.eclipse.debug.examples.ui/META-INF/MANIFEST.MF b/org.eclipse.debug.examples.ui/META-INF/MANIFEST.MF index a6f793240..1aef3d1ad 100644 --- a/org.eclipse.debug.examples.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.debug.examples.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.debug.examples.ui;singleton:=true -Bundle-Version: 1.3.100.qualifier +Bundle-Version: 1.4.0.qualifier Bundle-Activator: org.eclipse.debug.examples.ui.pda.DebugUIPlugin Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.resources, diff --git a/org.eclipse.debug.examples.ui/plugin.xml b/org.eclipse.debug.examples.ui/plugin.xml index f773254fd..5b1382d09 100644 --- a/org.eclipse.debug.examples.ui/plugin.xml +++ b/org.eclipse.debug.examples.ui/plugin.xml @@ -229,7 +229,6 @@ </adapter> </factory> --> -<!-- FLEXIBLE HIERARCHY EXAMPLE <factory adaptableType="org.eclipse.debug.examples.core.pda.model.PDADebugTarget" class="org.eclipse.debug.examples.ui.pda.adapters.AdapterFactory"> @@ -240,7 +239,13 @@ type="org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory"> </adapter> </factory> ---> + <factory + adaptableType="org.eclipse.debug.examples.core.pda.model.PDAStackFrame" + class="org.eclipse.debug.examples.ui.pda.adapters.AdapterFactory"> + <adapter + type="org.eclipse.debug.internal.ui.viewers.model.provisional.IViewActionProvider"> + </adapter> + </factory> </extension> <extension diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/AdapterFactory.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/AdapterFactory.java index 3e4153fd5..7034432bc 100644 --- a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/AdapterFactory.java +++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/AdapterFactory.java @@ -13,8 +13,10 @@ package org.eclipse.debug.examples.ui.pda.adapters; import org.eclipse.core.runtime.IAdapterFactory; import org.eclipse.debug.examples.core.pda.model.PDADebugTarget; +import org.eclipse.debug.examples.core.pda.model.PDAStackFrame; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewActionProvider; /** @@ -26,6 +28,7 @@ public class AdapterFactory implements IAdapterFactory { private static IElementContentProvider fgTargetAdapter = new PDADebugTargetContentProvider(); private static IModelProxyFactory fgFactory = new ModelProxyFactory(); + private static IViewActionProvider fgViewActionProvider = new PDAViewActionProvider(); public Object getAdapter(Object adaptableObject, Class adapterType) { if (IElementContentProvider.class.equals(adapterType)) { @@ -38,11 +41,16 @@ public class AdapterFactory implements IAdapterFactory { return fgFactory; } } + if (IViewActionProvider.class.equals(adapterType)) { + if (adaptableObject instanceof PDAStackFrame) { + return fgViewActionProvider; + } + } return null; } public Class[] getAdapterList() { - return new Class[]{IElementContentProvider.class, IModelProxyFactory.class}; + return new Class[]{IElementContentProvider.class, IModelProxyFactory.class, IViewActionProvider.class}; } } diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDAViewActionProvider.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDAViewActionProvider.java new file mode 100644 index 000000000..cb575878e --- /dev/null +++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDAViewActionProvider.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2012 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial implementation + */ +package org.eclipse.debug.examples.ui.pda.adapters; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewActionProvider; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.IDebugView; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; + +/** + * View action provider that returns a custom find action for the PDA debugger + * in the variables view. + * @since 3.8 + */ +public class PDAViewActionProvider implements IViewActionProvider { + + Map fActions = new HashMap(); + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IViewActionProvider#getAction(org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, java.lang.String) + */ + public IAction getAction(IPresentationContext presentationContext, String actionID) { + if (presentationContext.getId().equals(IDebugUIConstants.ID_VARIABLE_VIEW) && + IDebugView.FIND_ACTION.equals(actionID) ) + { + Action action = (Action)fActions.get(presentationContext); + if (action == null) { + action = new PDAVirtualFindAction(presentationContext); + fActions.put(presentationContext, action); + } + return action; + } + return null; + } +} diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDAVirtualFindAction.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDAVirtualFindAction.java new file mode 100644 index 000000000..bf0792e96 --- /dev/null +++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDAVirtualFindAction.java @@ -0,0 +1,317 @@ +/******************************************************************************* + * Copyright (c) 2004, 2010 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 implementation + * Pawel Piech (Wind River) - added a breadcrumb mode to Debug view (Bug 252677) + * Wind River Systems - refactored on top of VirtualTreeModelViewer + *******************************************************************************/ +package org.eclipse.debug.examples.ui.pda.adapters; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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.IDebugHelpContextIds; +import org.eclipse.debug.internal.ui.viewers.FindElementDialog; +import org.eclipse.debug.internal.ui.viewers.model.ILabelUpdateListener; +import org.eclipse.debug.internal.ui.viewers.model.TimeTriggeredProgressMonitorDialog; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +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.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; +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.viewers.model.provisional.VirtualItem; +import org.eclipse.debug.internal.ui.viewers.model.provisional.VirtualTreeModelViewer; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.IDebugView; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.IWorkbenchCommandConstants; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.texteditor.IUpdate; + +/** + * Action which prompts user with a filtered list selection dialog to find an element in tree. + * + * @since 3.3 + */ +public class PDAVirtualFindAction extends Action implements IUpdate { + + private TreeModelViewer fClientViewer; + + protected class VirtualViewerListener implements IViewerUpdateListener, ILabelUpdateListener { + + private boolean fViewerUpdatesComplete = false; + private boolean fLabelUpdatesComplete = false; + private IProgressMonitor fProgressMonitor; + private int fRemainingUpdatesCount = 0; + + public void labelUpdateStarted(ILabelUpdate update) {} + public void labelUpdateComplete(ILabelUpdate update) { + incrementProgress(1); + } + public void labelUpdatesBegin() { + fLabelUpdatesComplete = false; + } + public void labelUpdatesComplete() { + fLabelUpdatesComplete = true; + completeProgress(); + } + + public void updateStarted(IViewerUpdate update) {} + public void updateComplete(IViewerUpdate update) { + if (update instanceof IChildrenUpdate) { + incrementProgress(((IChildrenUpdate)update).getLength()); + } + } + public void viewerUpdatesBegin() { + fViewerUpdatesComplete = false; + } + public void viewerUpdatesComplete() { + fViewerUpdatesComplete = true; + completeProgress(); + } + + private void completeProgress() { + IProgressMonitor pm; + synchronized (this) { + pm = fProgressMonitor; + } + if (pm != null && fLabelUpdatesComplete && fViewerUpdatesComplete) { + pm.done(); + } + } + + private void incrementProgress(int count) { + IProgressMonitor pm; + synchronized (this) { + pm = fProgressMonitor; + fRemainingUpdatesCount -= count; + } + if (pm != null && fLabelUpdatesComplete && fViewerUpdatesComplete) { + pm.worked(count); + } + } + + } + + private static class FindLabelProvider extends LabelProvider { + private VirtualTreeModelViewer fVirtualViewer; + private Map fTextCache = new HashMap(); + public FindLabelProvider(VirtualTreeModelViewer viewer, List items) { + fVirtualViewer = viewer; + for (int i = 0; i < items.size(); i++) { + VirtualItem item = (VirtualItem)items.get(i); + fTextCache.put(item, fVirtualViewer.getText(item, 0)); + } + } + + public Image getImage(Object element) { + return fVirtualViewer.getImage((VirtualItem) element, 0); + } + + public String getText(Object element) { + return (String)fTextCache.get(element); + } + } + + public PDAVirtualFindAction(IPresentationContext context) { + setText("Find"); + setId(DebugUIPlugin.getUniqueIdentifier() + ".FindElementAction"); //$NON-NLS-1$ + PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IDebugHelpContextIds.FIND_ELEMENT_ACTION); + setActionDefinitionId(IWorkbenchCommandConstants.EDIT_FIND_AND_REPLACE); + fClientViewer = (TreeModelViewer)((IDebugView)context.getPart()).getViewer(); + } + + protected VirtualTreeModelViewer initVirtualViewer(TreeModelViewer clientViewer, VirtualViewerListener listener) { + Object input = clientViewer.getInput(); + ModelDelta stateDelta = new ModelDelta(input, IModelDelta.NO_CHANGE); + clientViewer.saveElementState(TreePath.EMPTY, stateDelta, IModelDelta.EXPAND); + listener.fRemainingUpdatesCount = calcUpdatesCount(stateDelta); + VirtualTreeModelViewer fVirtualViewer = new VirtualTreeModelViewer( + clientViewer.getDisplay(), + SWT.NONE, + makeVirtualPresentationContext(clientViewer.getPresentationContext())); + fVirtualViewer.addViewerUpdateListener(listener); + fVirtualViewer.addLabelUpdateListener(listener); + fVirtualViewer.setInput(input); + if (fVirtualViewer.canToggleColumns()) { + fVirtualViewer.setShowColumns(clientViewer.isShowColumns()); + } + fVirtualViewer.updateViewer(stateDelta); + return fVirtualViewer; + } + + protected IPresentationContext makeVirtualPresentationContext(final IPresentationContext clientViewerContext) { + return new PresentationContext(clientViewerContext.getId()) { + + { + String[] clientProperties = clientViewerContext.getProperties(); + for (int i = 0; i < clientProperties.length; i++) { + setProperty(clientProperties[i], clientViewerContext.getProperty(clientProperties[i])); + } + + } + + public String[] getColumns() { + String[] clientColumns = super.getColumns(); + + if (clientColumns == null || clientColumns.length == 0) { + // No columns are used. + return null; + } + + // Try to find the name column. + for (int i = 0; i < clientColumns.length; i++) { + if (IDebugUIConstants.COLUMN_ID_VARIABLE_NAME.equals(clientColumns[i])) { + return new String[] { IDebugUIConstants.COLUMN_ID_VARIABLE_NAME }; + } + } + + return new String[] { clientColumns[0] }; + } + }; + } + + public void run() { + final VirtualViewerListener listener = new VirtualViewerListener(); + VirtualTreeModelViewer virtualViewer = initVirtualViewer(fClientViewer, listener); + + ProgressMonitorDialog dialog = new TimeTriggeredProgressMonitorDialog(fClientViewer.getControl().getShell(), 500); + final IProgressMonitor monitor = dialog.getProgressMonitor(); + dialog.setCancelable(true); + + try { + dialog.run( + true, true, + new IRunnableWithProgress() { + public void run(final IProgressMonitor m) throws InvocationTargetException, InterruptedException { + synchronized(listener) { + listener.fProgressMonitor = m; + listener.fProgressMonitor.beginTask(DebugUIPlugin.removeAccelerators(getText()), listener.fRemainingUpdatesCount); + } + + while ((!listener.fLabelUpdatesComplete || !listener.fViewerUpdatesComplete) && !listener.fProgressMonitor.isCanceled()) { + Thread.sleep(1); + } + synchronized(listener) { + listener.fProgressMonitor = null; + } + } + }); + } catch (InvocationTargetException e) { + DebugUIPlugin.log(e); + return; + } catch (InterruptedException e) { + return; + } + + VirtualItem root = virtualViewer.getTree(); + if (!monitor.isCanceled()) { + List list = new ArrayList(); + collectAllChildren(root, list); + FindLabelProvider labelProvider = new FindLabelProvider(virtualViewer, list); + VirtualItem result = performFind(list, labelProvider); + if (result != null) { + setSelectionToClient(virtualViewer, labelProvider, result); + } + } + + virtualViewer.removeLabelUpdateListener(listener); + virtualViewer.removeViewerUpdateListener(listener); + virtualViewer.dispose(); + } + + private int calcUpdatesCount(IModelDelta stateDelta) { + final int[] count = new int[] {0}; + stateDelta.accept( new IModelDeltaVisitor() { + public boolean visit(IModelDelta delta, int depth) { + if ((delta.getFlags() & IModelDelta.EXPAND) != 0) { + count[0] += delta.getChildCount(); + return true; + } + return false; + } + }); + + // Double it to account for separate element and label update ticks. + return count[0] * 2; + } + + private void collectAllChildren(VirtualItem element, List collect) { + VirtualItem[] children = element.getItems(); + if (children != null) { + for (int i = 0; i < children.length; i++) { + if (!children[i].needsLabelUpdate()) { + collect.add(children[i]); + collectAllChildren(children[i], collect); + } + } + } + } + + protected VirtualItem performFind(List items, FindLabelProvider labelProvider) { + FindElementDialog dialog = new FindElementDialog( + fClientViewer.getControl().getShell(), + labelProvider, + items.toArray()); + dialog.setTitle("PDA Variables View Find"); + dialog.setMessage("&Specify an element to select (? = any character, * = any String):"); + if (dialog.open() == Window.OK) { + Object[] elements = dialog.getResult(); + if (elements.length == 1) { + return (VirtualItem)elements[0]; + } + } + return null; + } + + protected void setSelectionToClient(VirtualTreeModelViewer virtualViewer, ILabelProvider labelProvider, VirtualItem findItem) { + virtualViewer.getTree().setSelection(new VirtualItem[] { findItem } ); + ModelDelta stateDelta = new ModelDelta(virtualViewer.getInput(), IModelDelta.NO_CHANGE); + virtualViewer.saveElementState(TreePath.EMPTY, stateDelta, IModelDelta.SELECT); + fClientViewer.updateViewer(stateDelta); + + ISelection selection = fClientViewer.getSelection(); + if (!selection.isEmpty() && + selection instanceof IStructuredSelection && + ((IStructuredSelection)selection).getFirstElement().equals(findItem.getData()) ) { + } else { + DebugUIPlugin.errorDialog( + fClientViewer.getControl().getShell(), + "Error", + "Could not select item:" + labelProvider.getText(findItem), + new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Element no longer in viewer.")); + } + } + + public void update() { + setEnabled( fClientViewer.getInput() != null && fClientViewer.getChildCount(TreePath.EMPTY) > 0 ); + } + +} |