diff options
author | Jonah Graham | 2017-08-18 20:24:31 +0000 |
---|---|---|
committer | Jonah Graham | 2017-08-18 20:24:31 +0000 |
commit | fb0df4a13035064a5d60844dcca49df3053d5b32 (patch) | |
tree | 82ad9724582c25c52e8ee7e33761458a09d70594 /memory | |
parent | 9913afd1eb136b48bd298eae33f3f434692d6267 (diff) | |
download | org.eclipse.cdt-fb0df4a13035064a5d60844dcca49df3053d5b32.tar.gz org.eclipse.cdt-fb0df4a13035064a5d60844dcca49df3053d5b32.tar.xz org.eclipse.cdt-fb0df4a13035064a5d60844dcca49df3053d5b32.zip |
Cosmetics.
Fix bad line endings in memory/**/*.java
Change-Id: I34b4966b7d3fd965ea43b2f676b77ae9b7b4f2aa
Diffstat (limited to 'memory')
2 files changed, 1494 insertions, 1494 deletions
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/MemoryBrowser.java b/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/MemoryBrowser.java index 9f3eaf7e0a9..9dfdd2dff11 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/MemoryBrowser.java +++ b/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/MemoryBrowser.java @@ -1,1395 +1,1395 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2015 Wind River Systems, Inc. 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:
- * Ted R Williams (Wind River Systems, Inc.) - initial implementation
- * Ted R Williams (Mentor Graphics, Inc.) - address space enhancements
- * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781)
- *******************************************************************************/
-
-package org.eclipse.cdt.debug.ui.memory.memorybrowser;
-
-import java.lang.reflect.Type;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.cdt.debug.core.model.provisional.IMemoryRenderingViewportProvider;
-import org.eclipse.cdt.debug.core.model.provisional.IMemorySpaceAwareMemoryBlockRetrieval;
-import org.eclipse.cdt.debug.internal.core.CRequest;
-import org.eclipse.cdt.debug.ui.memory.memorybrowser.api.IMemoryBrowser;
-import org.eclipse.cdt.debug.ui.provisional.IRepositionableMemoryRendering2;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.SafeRunner;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.debug.core.DebugEvent;
-import org.eclipse.debug.core.DebugException;
-import org.eclipse.debug.core.DebugPlugin;
-import org.eclipse.debug.core.IDebugEventSetListener;
-import org.eclipse.debug.core.ILaunch;
-import org.eclipse.debug.core.model.IDebugTarget;
-import org.eclipse.debug.core.model.IMemoryBlock;
-import org.eclipse.debug.core.model.IMemoryBlockExtension;
-import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
-import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension;
-import org.eclipse.debug.core.model.MemoryByte;
-import org.eclipse.debug.internal.ui.memory.MemoryRenderingManager;
-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.debug.ui.memory.IMemoryRendering;
-import org.eclipse.debug.ui.memory.IMemoryRenderingContainer;
-import org.eclipse.debug.ui.memory.IMemoryRenderingSite;
-import org.eclipse.debug.ui.memory.IMemoryRenderingSynchronizationService;
-import org.eclipse.debug.ui.memory.IMemoryRenderingType;
-import org.eclipse.debug.ui.memory.IRepositionableMemoryRendering;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.action.IMenuListener;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.resource.ColorRegistry;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.util.IPropertyChangeListener;
-import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.jface.util.SafeRunnable;
-import org.eclipse.jface.viewers.IBasicPropertyConstants;
-import org.eclipse.jface.viewers.ILabelDecorator;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.ISelectionProvider;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CTabFolder;
-import org.eclipse.swt.custom.CTabFolder2Adapter;
-import org.eclipse.swt.custom.CTabFolderEvent;
-import org.eclipse.swt.custom.CTabItem;
-import org.eclipse.swt.custom.StackLayout;
-import org.eclipse.swt.dnd.DND;
-import org.eclipse.swt.dnd.DropTarget;
-import org.eclipse.swt.dnd.DropTargetAdapter;
-import org.eclipse.swt.dnd.DropTargetEvent;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.IViewSite;
-import org.eclipse.ui.IWorkbenchActionConstants;
-import org.eclipse.ui.IWorkbenchPreferenceConstants;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.part.ViewPart;
-import org.eclipse.ui.progress.UIJob;
-import org.eclipse.ui.progress.WorkbenchJob;
-
-/**
- * A lightweight rendering container.
- *
- * Debug model requirements:
- * IMemoryBlockExtension (IMemoryBlock not supported)
- * IMemoryBlockRetrievalExtension
- * <p>
- * Rendering requirements:
- * IRepositionableMemoryRendering
- *
- */
-
-@SuppressWarnings("restriction") /* Debug Platform's Flexible hierarchy is still provisional */
-
-public class MemoryBrowser extends ViewPart implements IDebugContextListener, IMemoryRenderingSite, IDebugEventSetListener, IMemoryBrowser
-{
- public static final String ID = "org.eclipse.cdt.debug.ui.memory.memorybrowser.MemoryBrowser"; //$NON-NLS-1$
-
- protected StackLayout fStackLayout;
- private Composite fRenderingsComposite;
- private GoToAddressBarWidget fGotoAddressBar;
- private DropTarget fDropTarget;
- private Control fGotoAddressBarControl;
- private Combo fGotoMemorySpaceControl;
- private Label fUnsupportedLabel;
- private Composite fMainComposite;
- private String defaultRenderingTypeId = null;
- private IMemoryRendering fActiveRendering;
-
- /**
- * Every memory retrieval object is given its own tab folder. Typically all
- * elements of a "process" (process, threads, frames) have the same
- * retrieval object.
- */
- private Map<IMemoryBlockRetrieval,CTabFolder> fContextFolders = new HashMap<IMemoryBlockRetrieval,CTabFolder> ();
-
- private List<IMemoryRenderingContainer> fCurrentContainers = new ArrayList<IMemoryRenderingContainer>();
-
- private final static String KEY_CONTEXT = "CONTEXT"; //$NON-NLS-1$
- private final static String KEY_CONTAINER = "CONTAINER"; //$NON-NLS-1$
- private final static String KEY_RENDERING_TYPE = "RENDERING_TYPE"; //$NON-NLS-1$
-
- /**
- * Property we attach to a CTabItem to track the retrieval object we use to
- * create memory blocks on the tab's behalf. Value is an
- * {@link IMemoryBlockRetrieval}
- */
- private final static String KEY_RETRIEVAL = "RETRIEVAL"; //$NON-NLS-1$
-
- /**
- * Property we attach to a CTabItem to track the memory space it's
- * associated with. Value is a memory space ID (String), or null if n/a
- */
- private final static String KEY_MEMORY_SPACE = "MEMORY_SPACE"; //$NON-NLS-1$
-
- /**
- * Property we attach to a CTabItem to track what renderings have been
- * created on its behalf. There will be more than one rendering if the
- * backend supports memory spaces, there is more than one such space, and
- * the user has viewed memory in multiple memory spaces within that tab.
- * The value is a map of memory-space-ID==>IMemoryRendering.
- */
- private final static String KEY_RENDERINGS = "RENDERINGS"; //$NON-NLS-1$
-
- /**
- * Property we attach to a CTabItem to track the active rendering in the
- * tab. The value is an IMemoryRendering.
- */
- private final static String KEY_RENDERING = "RENDERING"; //$NON-NLS-1$
-
- /**
- * Property we attach to a CTabItem to track what memory blocks have been
- * created on its behalf. There can be multiple when dealing with memory
- * spaces, for the same reasons there can be multiple renderings. There is a
- * 1:1:1 association between rendering, block and memory space. The value is
- * a list of IMemoryBlockExtension
- */
- private final static String KEY_MEMORY_BLOCKS = "MEMORY_BLOCKS"; //$NON-NLS-1$
-
- /**
- * Property we attach to a CTabItem to track the expression we used to
- * create memory blocks on the tab's behalf. Value is a String.
- */
- private final static String KEY_EXPRESSION = "EXPRESSION"; //$NON-NLS-1$
-
- /**
- * Property we attach to a CTabItem to track the address associated with
- * KEY_EXPRESSION. Value is a BigInteger
- */
- private final static String KEY_EXPRESSION_ADDRESS = "EXPRESSION_ADDRESS"; //$NON-NLS-1$
-
- public static final String PREF_DEFAULT_RENDERING = "org.eclipse.cdt.debug.ui.memory.memorybrowser.defaultRendering"; //$NON-NLS-1$
-
- /**
- * The text we use in the combobox to represent no memory space specification
- */
- private static final String NA_MEMORY_SPACE_ID = " -----"; //$NON-NLS-1$
-
- public MemoryBrowser() {
- }
-
- public Control getControl() {
- return fMainComposite;
- }
-
- /*
- * Handles DnD from other views.
- */
- private class MemoryDropAdapter extends DropTargetAdapter {
- /*
- * @see org.eclipse.swt.dnd.DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent)
- */
- @Override
- public void drop(final DropTargetEvent event) {
- if (TextTransfer.getInstance().isSupportedType( event.currentDataType )) {
- if ( event.data instanceof String ) {
- fGotoAddressBar.setExpressionText( (String) event.data );
- performGo(false);
- }
- }
- }
-
- /*
- * @see org.eclipse.swt.dnd.DropTargetListener#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
- */
- @Override
- public void dragEnter(DropTargetEvent event) {
- event.detail = DND.DROP_COPY;
- event.feedback = DND.FEEDBACK_NONE;
- }
- }
-
- @Override
- public void createPartControl(Composite parent) {
- // set default rendering type. use the traditional rendering if available. fallback on first registered type.
- // this should eventually be configurable via a preference page.
- boolean isDefaultRenderingAvailable = false;
- IPreferenceStore store = MemoryBrowserPlugin.getDefault().getPreferenceStore();
- String defaultRendering = store.getString(PREF_DEFAULT_RENDERING);
- if(defaultRendering == null || defaultRendering.trim().length() == 0)
- {
- defaultRendering = "org.eclipse.cdt.debug.ui.memory.traditional.TraditionalRendering"; //$NON-NLS-1$
- }
-
- IMemoryRenderingType[] types = getRenderingTypes();
- for(final IMemoryRenderingType type : types)
- {
- if(type.getId().equals(defaultRendering))
- {
- isDefaultRenderingAvailable = true;
- break;
- }
- }
- if(isDefaultRenderingAvailable)
- defaultRenderingTypeId = defaultRendering;
- else if(types.length > 0)
- defaultRenderingTypeId = types[0].getId();
-
- getSite().setSelectionProvider(new SelectionProviderAdapter());
-
- fMainComposite = new Composite(parent, SWT.NONE);
-
- FormLayout layout = new FormLayout();
- layout.spacing = 0;
- fMainComposite.setLayout(layout);
-
- fGotoMemorySpaceControl = new Combo(fMainComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
- fGotoAddressBar = new GoToAddressBarWidget();
- fGotoAddressBarControl = fGotoAddressBar.createControl(fMainComposite);
-
- if (fDropTarget == null) {
- fDropTarget = new DropTarget(fGotoAddressBarControl, DND.DROP_COPY | DND.DROP_DEFAULT);
- fDropTarget.setTransfer( new Transfer[] { TextTransfer.getInstance() });
- fDropTarget.addDropListener(new MemoryDropAdapter());
- }
-
- fGotoAddressBar.getButton(IDialogConstants.OK_ID).addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- performGo(false);
- }
- });
-
- fGotoAddressBar.getButton(GoToAddressBarWidget.ID_GO_NEW_TAB).addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- performGo(true);
- }
- });
-
- fGotoAddressBar.getExpressionWidget().addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- performGo(false);
- }
- @Override
- public void widgetSelected(SelectionEvent e) {
- performGo(false);
- }
- });
-
- fGotoMemorySpaceControl.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- if(fGotoMemorySpaceControl.getItemCount() >= 2) {
- final CTabFolder activeFolder = (CTabFolder) fStackLayout.topControl;
- if (activeFolder != null) {
- final Object context = activeFolder.getData(KEY_CONTEXT);
- fGotoAddressBar.loadSavedExpressions(context, fGotoMemorySpaceControl.getText());
- performGo(false);
- }
- }
- }
- });
-
-
- FormData data = new FormData();
- data.top = new FormAttachment(0);
- data.left = new FormAttachment(fGotoMemorySpaceControl);
- data.right = new FormAttachment(100);
- fGotoAddressBarControl.setLayoutData(data);
-
- fRenderingsComposite = new Composite(fMainComposite, SWT.NONE);
- data = new FormData();
- data.top = new FormAttachment(fGotoAddressBarControl);
- data.left = new FormAttachment(0);
- data.right = new FormAttachment(100);
- data.bottom = new FormAttachment(100);
- fRenderingsComposite.setLayoutData(data);
-
- fStackLayout = new StackLayout();
-
- fRenderingsComposite.setLayout(fStackLayout);
-
- fUnsupportedLabel = new Label(fRenderingsComposite, SWT.NONE);
- fUnsupportedLabel.setText(""); //$NON-NLS-1$
-
- handleUnsupportedSelection();
-
- PlatformUI.getWorkbench().getHelpSystem().setHelp(fMainComposite, MemoryBrowserPlugin.PLUGIN_ID);
- makeActions();
- hookContextMenu();
- contributeToActionBars();
-
- Object selection = null;
- IDebugContextService contextService =
- DebugUITools.getDebugContextManager().getContextService(getSite().getWorkbenchWindow());
- if (isBug145635Patched()) {
- String presentationContextId = getPresentationContextId();
- contextService.addDebugContextListener(this, presentationContextId);
- selection = contextService.getActiveContext(presentationContextId);
- } else {
- DebugUITools.addPartDebugContextListener(getSite(), this);
- selection = contextService.getActiveContext(getSite().getId(), ((IViewSite)getSite()).getSecondaryId());
- }
-
- DebugPlugin.getDefault().addDebugEventListener(this);
-
- if(selection instanceof StructuredSelection)
- handleDebugContextChanged(((StructuredSelection) selection).getFirstElement());
- }
-
- private boolean isBug145635Patched() {
- Type[] managerTypes = DebugUITools.getDebugContextManager().getClass().getGenericInterfaces();
- for (int i = 0; i < managerTypes.length; i++) {
- if (managerTypes[i] instanceof Class<?>) {
- Class<?> clazz = (Class<?>)managerTypes[i];
- if ("org.eclipse.debug.ui.contexts.IBug145635Marker".equals(clazz.getName()) ) { //$NON-NLS-1$
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Clears the expression history for the active tab
- */
- public void clearExpressionHistoryForActiveTab() {
- final CTabFolder activeFolder = (CTabFolder) fStackLayout.topControl;
- if (activeFolder != null) {
- final Object context = activeFolder.getData(KEY_CONTEXT);
- fGotoAddressBar.clearExpressionHistory(context);
- }
- }
-
- /**
- * Returns the presentation context id for this view. Used to support the
- * pin and clone feature patch from bug 145635.
- *
- * @return context id
- */
- private String getPresentationContextId() {
- IViewSite site = (IViewSite)getSite();
- return site.getId() + (site.getSecondaryId() != null ? (":" + site.getSecondaryId()) : ""); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- @Override
- public void dispose() {
- if (fDropTarget != null) {
- fDropTarget.dispose();
- fDropTarget = null;
- }
- DebugPlugin.getDefault().removeDebugEventListener(this);
- IDebugContextService contextService =
- DebugUITools.getDebugContextManager().getContextService(getSite().getWorkbenchWindow());
- if (isBug145635Patched()) {
- String presentationContextId = getPresentationContextId();
- contextService.removeDebugContextListener(this, presentationContextId);
- } else {
- DebugUITools.removePartDebugContextListener(getSite(), this);
- }
- super.dispose();
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])
- */
- public void handleDebugEvents(DebugEvent[] events) {
- for (DebugEvent event: events) {
- Object source = event.getSource();
- if (event.getKind() == DebugEvent.TERMINATE && source instanceof IMemoryBlockRetrieval) {
- releaseTabFolder((IMemoryBlockRetrieval)source);
- }
- }
- }
-
- public IMemoryRenderingContainer getContainer(String id) {
- return null;
- }
-
- public IMemoryRenderingContainer[] getMemoryRenderingContainers() {
- IMemoryRenderingContainer[] containerList = new IMemoryRenderingContainer[fCurrentContainers.size()];
- for ( int idx = 0 ; idx < fCurrentContainers.size() ; idx ++ ) {
- containerList[ idx ] = fCurrentContainers.get( idx );
- }
- return containerList;
- }
-
- public IMemoryRenderingSynchronizationService getSynchronizationService() {
- return null;
- }
-
- private void handleUnsupportedSelection() {
- fStackLayout.topControl = fUnsupportedLabel;
- if(!fGotoAddressBarControl.isDisposed()) {
- fGotoAddressBarControl.setVisible(false);
- }
- if(!fGotoMemorySpaceControl.isDisposed()) {
- fGotoMemorySpaceControl.setVisible(false);
- }
- }
-
- private void performGo(boolean inNewTab) {
- // Index zero is the 'auto' (n/a) memory space entry, unless the backend
- // said we need to force a memory space selection
- String memorySpace = null;
- if (fGotoMemorySpaceControl.isVisible()) {
- memorySpace = fGotoMemorySpaceControl.getText();
- if (memorySpace.equals(NA_MEMORY_SPACE_ID)) {
- memorySpace = null;
- }
- assert (memorySpace == null) || (memorySpace.length() > 0);
- }
-
- String expression = fGotoAddressBar.getExpressionText();
- if (expression.length() > 0) {
- final CTabFolder activeFolder = (CTabFolder) fStackLayout.topControl;
- Object context = null;
- if (activeFolder != null) {
- context = activeFolder.getData(KEY_CONTEXT);
- }
- fGotoAddressBar.addExpressionToHistory(context, expression, memorySpace);
- performGo(inNewTab, expression, memorySpace);
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.cdt.debug.ui.memory.memorybrowser.api.IMemoryBrowser#getActiveRetrieval()
- */
- public IMemoryBlockRetrieval getActiveRetrieval() {
- final CTabFolder activeFolder = (CTabFolder) fStackLayout.topControl;
- if (activeFolder == null)
- return null;
-
- return (IMemoryBlockRetrieval) activeFolder.getData(KEY_RETRIEVAL);
- }
-
- public void performGo(boolean inNewTab, final String expression, final String memorySpaceId) {
- final CTabFolder activeFolder = (CTabFolder) fStackLayout.topControl;
- if (activeFolder != null) {
- final IMemoryBlockRetrieval retrieval = (IMemoryBlockRetrieval) activeFolder.getData(KEY_RETRIEVAL);
- final Object context = activeFolder.getData(KEY_CONTEXT);
- IMemoryRendering rendering = null;
-
- CTabItem item = activeFolder.getSelection();
- if (inNewTab || item == null)
- {
- try {
- item = createTab(activeFolder, activeFolder.getSelectionIndex() + 1);
- rendering = populateTabWithRendering(item, retrieval, context, memorySpaceId, expression);
- fContextFolders.put(retrieval, activeFolder);
- activeFolder.setSelection(item);
- getSite().getSelectionProvider().setSelection(new StructuredSelection(item.getData(KEY_RENDERING)));
- handleTabActivated(item);
- } catch (DebugException e1) {
- fGotoAddressBar.handleExpressionStatus(new Status(Status.ERROR, MemoryBrowserPlugin.PLUGIN_ID,
- Messages.getString("MemoryBrowser.FailedToGoToAddressTitle"), e1)); //$NON-NLS-1$
- if (item != null) {
- item.dispose();
- }
- return;
- }
- } else {
- // Tab is already in place. However, the user may have selected
- // a different memory space. If so, that requires us to switch
- // out the rendering in the tab with either a new one or an
- // existing one already associated with that memory space.
- String oldMemorySpaceId = (String)activeFolder.getSelection().getData(KEY_MEMORY_SPACE);
- assert oldMemorySpaceId == null || !oldMemorySpaceId.equals(NA_MEMORY_SPACE_ID) : "should be null reference or an explicit, valid memory space ID (not including '----')"; //$NON-NLS-1$
- if ((oldMemorySpaceId != null && !oldMemorySpaceId.equals(memorySpaceId))
- || (oldMemorySpaceId == null && memorySpaceId != null)) {
- try {
- rendering = populateTabWithRendering(item, retrieval, context, memorySpaceId, expression);
- activeFolder.setSelection(item);
- getSite().getSelectionProvider().setSelection(new StructuredSelection(item.getData(KEY_RENDERING)));
- handleTabActivated(item);
- } catch (DebugException e) {
- fGotoAddressBar.handleExpressionStatus(new Status(Status.ERROR, MemoryBrowserPlugin.PLUGIN_ID,
- Messages.getString("MemoryBrowser.FailedToGoToAddressTitle"), e)); //$NON-NLS-1$
- return;
- }
- }
- }
-
- if (rendering == null) {
- rendering = (IRepositionableMemoryRendering) activeFolder.getSelection().getData(KEY_RENDERING);
- }
-
- if (retrieval instanceof IMemoryBlockRetrievalExtension &&
- rendering instanceof IRepositionableMemoryRendering) {
- final IRepositionableMemoryRendering renderingFinal = (IRepositionableMemoryRendering) rendering;
- new Thread() {
- @Override
- public void run() {
- try {
- final BigInteger newBase = getExpressionAddress(retrieval, expression, context, memorySpaceId);
- IMemoryBlockExtension block = (IMemoryBlockExtension) renderingFinal.getMemoryBlock();
- if (block.supportBaseAddressModification()) {
- block.setBaseAddress(newBase);
- }
- if(renderingFinal instanceof IRepositionableMemoryRendering2) {
- ((IRepositionableMemoryRendering2)renderingFinal).goToAddress(newBase, expression);
- }
- else {
- renderingFinal.goToAddress(newBase);
- }
-
- runOnUIThread(new Runnable(){
- public void run() {
- CTabItem selection = activeFolder.getSelection();
- selection.setData(KEY_EXPRESSION, expression);
- selection.setData(KEY_EXPRESSION_ADDRESS, newBase);
- fGotoAddressBar.handleExpressionStatus(Status.OK_STATUS);
- updateLabel(selection, renderingFinal);
- }
- });
- } catch (final DebugException e1) {
- // widgets update require Display
- runOnUIThread(new Runnable(){
- public void run() {
- fGotoAddressBar.handleExpressionStatus(new Status(Status.ERROR, MemoryBrowserPlugin.PLUGIN_ID,
- Messages.getString("MemoryBrowser.FailedToGoToAddressTitle"), e1)); //$NON-NLS-1$
- }
- });
- }
- }
- }.start();
- }
- }
- }
-
- private void updateLabel(CTabItem tab, IMemoryRendering rendering) {
- // The default is to use the label provided by the base rendering
- // interface.
- String label = rendering.getLabel();
-
- // If the rendering provides access to its viewport address (the first
- // address shown in the rendering, subject to scrolling), display that
- // in the tab rather than the expression that was used when the tab was
- // first created.
- if (rendering instanceof IMemoryRenderingViewportProvider) {
- BigInteger viewportAddress = ((IMemoryRenderingViewportProvider)rendering).getViewportAddress();
-
- // The base label generation puts the rendering type name in "<>" and
- // appends it to the label. Fish that out
- String renderingType = null;
- int i = label.indexOf('<');
- if (i >= 0) {
- renderingType = label.substring(i);
- }
-
- label = null;
-
- // If a memory space is involved, we want to include its ID in the label
- String memorySpaceID = (String)tab.getData(KEY_MEMORY_SPACE);
- if (memorySpaceID != null) {
- IMemoryBlockRetrieval retrieval = (IMemoryBlockRetrieval) tab.getParent().getData(KEY_RETRIEVAL);
- if (retrieval instanceof IMemorySpaceAwareMemoryBlockRetrieval) {
- label = ((IMemorySpaceAwareMemoryBlockRetrieval)retrieval).encodeAddress("0x" + viewportAddress.toString(16), memorySpaceID);
- }
- }
- if (label == null) {
- label = "0x" + viewportAddress.toString(16);
- }
-
- // If the expression that was went to ("Go") is not a hex address,
- // or it is but the user has scrolled/paged, then show the
- // expression after the viewport hex address. Additionally, if some
- // scrolling/paging has moved the viewport, also show the relative
- // displacement. E.g.,
- // "0x10020 - gSomeVar(+20) <Traditional>"
- // (for a tab where the user did a "Go" to "gSomeVar" then paged
- // down, and where gSomeVar is at 0x10000)
- //
- String expression = (String)tab.getData(KEY_EXPRESSION);
- BigInteger evaluatedAddress = (BigInteger)tab.getData(KEY_EXPRESSION_ADDRESS);
- if(expression != null && !expression.equals("0x" + viewportAddress.toString(16))) {
- label += " - " + expression;
- BigInteger delta = evaluatedAddress.subtract(viewportAddress);
- if (!delta.equals(BigInteger.ZERO)) {
- label += "(";
- label += delta.signum() < 0 ? '+' : '-';
- label += "0x" + delta.abs().toString(16) +")";
- }
- }
-
- label += ' ' + renderingType;;
-
- // Allow the memory block to customize the label. The platform's
- // Memory view support this (it was done in the call to
- // rendering.getLabel() above)
- IMemoryBlock block = rendering.getMemoryBlock();
- ILabelDecorator labelDec = (ILabelDecorator)block.getAdapter(ILabelDecorator.class);
- if (labelDec != null) {
- String newLabel = labelDec.decorateText(label, rendering);
- if (newLabel != null) {
- label = newLabel;
- }
- }
- }
-
- tab.setText(label);
- }
-
- private CTabFolder createTabFolder(Composite parent)
- {
- final CTabFolder folder = new CTabFolder(parent, SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM | SWT.FLAT);
-
- ColorRegistry reg = JFaceResources.getColorRegistry();
- Color c1 = reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_BG_START"), //$NON-NLS-1$
- c2 = reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_BG_END"); //$NON-NLS-1$
- folder.setSelectionBackground(new Color[] {c1, c2}, new int[] {100}, true);
- folder.setSelectionForeground(reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_TEXT_COLOR")); //$NON-NLS-1$
- folder.setSimple(PlatformUI.getPreferenceStore().getBoolean(IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS));
- folder.setBorderVisible(true);
-
- // listener to dispose rendering resources for each closed tab
- folder.addCTabFolder2Listener(new CTabFolder2Adapter() {
- @Override
- public void close(CTabFolderEvent event) {
- event.doit = true;
- CTabItem item = (CTabItem) event.item;
- disposeTab(item);
- }
- });
-
- // listener to dispose rendering resources for all tab items when view part is closed
- folder.addDisposeListener(new DisposeListener() {
- public void widgetDisposed(DisposeEvent e) {
- for(CTabItem tab : folder.getItems()) {
- disposeTab(tab);
- }
- folder.removeDisposeListener(this);
- }
- });
- return folder;
- }
-
- // these utility methods allow us restrict the scope of the unavoidable @SuppressWarnings
-
- @SuppressWarnings("unchecked")
- private static Map<String, IMemoryRendering> getRenderings(CTabItem tabItem) {
- return (Map<String, IMemoryRendering>)tabItem.getData(KEY_RENDERINGS);
- }
-
- @SuppressWarnings("unchecked")
- private static List<IMemoryBlockExtension> getMemoryBlocks(CTabItem tabItem) {
- return (List<IMemoryBlockExtension>)tabItem.getData(KEY_MEMORY_BLOCKS);
- }
-
-
- /**
- * dispose rendering resources associated with the tab item
- * @param item
- */
- private void disposeTab(CTabItem item ) {
- if (item.isDisposed())
- return;
-
- IMemoryRenderingContainer container = (IMemoryRenderingContainer) item.getData(KEY_CONTAINER);
- fCurrentContainers.remove( container );
- Map<String, IMemoryRendering> map = getRenderings(item);
- Collection<IMemoryRendering> renderings = map.values();
- for (IMemoryRendering rendering : renderings) {
- // always deactivate rendering before disposing it.
- rendering.deactivated();
- rendering.dispose();
- if (rendering == fActiveRendering) {
- fActiveRendering = null;
- getSite().getSelectionProvider().setSelection(new StructuredSelection());
- }
- }
- map.clear();
-
- List<IMemoryBlockExtension> blocks = getMemoryBlocks(item);
- for (IMemoryBlockExtension block : blocks) {
- try {
- block.dispose();
- } catch (DebugException e) {
- MemoryBrowserPlugin.getDefault().getLog().log(new Status(Status.ERROR, MemoryBrowserPlugin.PLUGIN_ID, "Could not dispose memory block", e)); //$NON-NLS-1$
- }
- }
- blocks.clear();
- }
-
- private CTabItem createTab(CTabFolder tabFolder, int index) {
- int swtStyle = SWT.CLOSE;
- CTabItem tab = new CTabItem(tabFolder, swtStyle, index);
- tab.setData(KEY_RENDERINGS, new HashMap<String, IMemoryRendering>());
- tab.setData(KEY_MEMORY_BLOCKS, new ArrayList<IMemoryBlock>());
- return tab;
- }
-
- private void hookContextMenu() {
- MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
- menuMgr.setRemoveAllWhenShown(true);
- menuMgr.addMenuListener(new IMenuListener() {
- public void menuAboutToShow(IMenuManager manager) {
- MemoryBrowser.this.fillContextMenu(manager);
- }
- });
- Menu menu = menuMgr.createContextMenu(getControl());
- getControl().setMenu(menu);
- }
-
- private void contributeToActionBars() {
- IActionBars bars = getViewSite().getActionBars();
- fillLocalPullDown(bars.getMenuManager());
- fillLocalToolBar(bars.getToolBarManager());
- }
-
- private void fillLocalPullDown(IMenuManager manager) {
-
-
- MenuManager sub = new MenuManager(Messages.getString("MemoryBrowser.DefaultRendering")); //$NON-NLS-1$
-
- for(final IMemoryRenderingType type : getRenderingTypes())
- {
- final Action action = new Action(
- type.getLabel(), IAction.AS_RADIO_BUTTON)
- {
- @Override
- public void run()
- {
- setDefaultRenderingTypeId(type.getId());
- }
- };
- action.setChecked(type.getId().equals(getDefaultRenderingTypeId()));
- sub.add(action);
- }
-
- manager.add(sub);
- manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
- }
-
- private void fillContextMenu(IMenuManager manager) {
- manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
- }
-
- private void fillLocalToolBar(IToolBarManager manager) {
- manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
- }
-
- private void makeActions() {
-
- }
-
- private IMemoryRenderingType[] getRenderingTypes()
- {
- return MemoryRenderingManager.getDefault().getRenderingTypes(new IMemoryBlockExtension(){
- public void connect(Object client) {}
- public void disconnect(Object client) {}
- public void dispose() throws DebugException {}
- public int getAddressSize() throws DebugException { return 0; }
- public int getAddressableSize() throws DebugException { return 0; }
- public BigInteger getBigBaseAddress() throws DebugException { return null; }
- public BigInteger getBigLength() throws DebugException { return null; }
- public MemoryByte[] getBytesFromAddress(BigInteger address, long units) throws DebugException { return null; }
- public MemoryByte[] getBytesFromOffset(BigInteger unitOffset, long addressableUnits) throws DebugException { return null; }
- public Object[] getConnections() { return null; }
- public String getExpression() { return null; }
- public BigInteger getMemoryBlockEndAddress() throws DebugException { return null; }
- public IMemoryBlockRetrieval getMemoryBlockRetrieval() { return null; }
- public BigInteger getMemoryBlockStartAddress() throws DebugException { return null; }
- public void setBaseAddress(BigInteger address) throws DebugException {}
- public void setValue(BigInteger offset, byte[] bytes) throws DebugException {}
- public boolean supportBaseAddressModification() throws DebugException { return false; }
- public boolean supportsChangeManagement() { return false; }
- public byte[] getBytes() throws DebugException { return null; }
- public long getLength() { return 0; }
- public long getStartAddress() { return 0; }
- public void setValue(long offset, byte[] bytes) throws DebugException {}
- public boolean supportsValueModification() { return false; }
- public IDebugTarget getDebugTarget() { return null; }
- public ILaunch getLaunch() { return null; }
- public String getModelIdentifier() { return null; }
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public Object getAdapter(Class adapter) { return null; }
- });
- }
-
- @Override
- public void setFocus() {
- getControl().setFocus();
- }
-
- public void debugContextChanged(DebugContextEvent event) {
- handleDebugContextChanged(((StructuredSelection) event.getContext()).getFirstElement());
- }
-
- private final class MemoryBrowserRenderingContainer implements
- IMemoryRenderingContainer {
- private final List<IMemoryRendering> renderings = new ArrayList<IMemoryRendering>();
-
- private MemoryBrowserRenderingContainer() {
- }
-
- public void addMemoryRendering(IMemoryRendering rendering) {
- // do not allow duplicated objects
- if (!renderings.contains(rendering)) {
- renderings.add(rendering);
- }
- }
-
- public IMemoryRendering getActiveRendering() {
- return renderings.isEmpty() ? null : renderings.get(renderings.size() -1);
- }
-
- public String getId() {
- return ID;
- }
-
- public String getLabel() {
- IMemoryRendering rendering = getActiveRendering();
- return rendering != null ? rendering.getLabel() : null;
- }
-
- public IMemoryRenderingSite getMemoryRenderingSite() {
- return MemoryBrowser.this;
- }
-
- public IMemoryRendering[] getRenderings() {
- return renderings.toArray(new IMemoryRendering[renderings.size()]);
- }
-
- public void removeMemoryRendering(IMemoryRendering rendering) {
- renderings.remove(rendering);
- }
- }
-
- private final class RenderingPropertyChangeListener implements
- IPropertyChangeListener {
- private final CTabItem tab;
- private final IMemoryRendering newRendering;
-
- private RenderingPropertyChangeListener(CTabItem tab,
- IMemoryRendering newRendering) {
- this.tab = tab;
- this.newRendering = newRendering;
- }
-
- public void propertyChange(final PropertyChangeEvent event) {
- WorkbenchJob job = new WorkbenchJob("MemoryBrowser PropertyChanged") { //$NON-NLS-1$
- @Override
- public IStatus runInUIThread(IProgressMonitor monitor) {
- if(tab.isDisposed())
- return Status.OK_STATUS;
-
- if (event.getProperty().equals(IBasicPropertyConstants.P_TEXT))
- updateLabel(tab, newRendering);
- return Status.OK_STATUS;
- }
- };
- job.setSystem(true);
- job.schedule();
- }
- }
-
- private class GetMemorySpacesRequest extends CRequest implements IMemorySpaceAwareMemoryBlockRetrieval.GetMemorySpacesRequest {
- String [] fMemorySpaces;
- public String[] getMemorySpaces() {
- return fMemorySpaces;
- }
- public void setMemorySpaces(String[] memorySpaceIds) {
- fMemorySpaces = memorySpaceIds;
- }
- }
-
- public void handleDebugContextChanged(final Object context) {
- if(defaultRenderingTypeId == null)
- return;
-
- IAdaptable adaptable = null;
- IMemoryBlockRetrieval retrieval = null;
- ILaunch launch = null;
-
- if(context instanceof IAdaptable)
- {
- adaptable = (IAdaptable) context;
- retrieval = ((IMemoryBlockRetrieval) adaptable.getAdapter(IMemoryBlockRetrieval.class));
- launch = ((ILaunch) adaptable.getAdapter(ILaunch.class));
- }
-
- if(retrieval != null && launch != null && !launch.isTerminated()) {
- if (retrieval instanceof IMemorySpaceAwareMemoryBlockRetrieval) {
- final IMemoryBlockRetrieval _retrieval = retrieval;
- ((IMemorySpaceAwareMemoryBlockRetrieval)retrieval).getMemorySpaces(context, new GetMemorySpacesRequest(){
- @Override
- public void done() {
- updateTab(_retrieval, context, isSuccess() ? getMemorySpaces() : new String[0]);
- }
- });
- }
- else {
- updateTab(retrieval, context, new String[0]);
- }
- }
- else {
- handleUnsupportedSelection();
- }
-
- fGotoMemorySpaceControl.pack(true);
- fStackLayout.topControl.getParent().layout(true);
- }
-
- /**
- * Called to update the tab once the asynchronous query for memory spaces
- * has returned a result.
- *
- * @param retrieval
- * the retrieval object associated with the newly active debug
- * context
- * @param context
- * the newly active context
- * @param memorySpaces
- * the memory spaces, if applicable. Otherwise an empty array.
- */
- private void updateTab(final IMemoryBlockRetrieval retrieval, final Object context, final String[] memorySpaces) {
- // GUI activity must be on the main thread
- runOnUIThread(new Runnable(){
- public void run() {
- if (fGotoAddressBarControl.isDisposed() || fGotoMemorySpaceControl.isDisposed()) {
- return;
- }
-
- fGotoAddressBarControl.setVisible(true);
-
- // If we've already created a tab folder for this retrieval
- // object, bring it to the forefront. Otherwise create the
- // folder.
- CTabFolder tabFolder = fContextFolders.get(retrieval);
- if(tabFolder != null) {
- fStackLayout.topControl = tabFolder;
- CTabItem tabItem = (CTabItem) tabFolder.getSelection();
- if ( tabItem != null ) {
- getSite().getSelectionProvider().setSelection(new StructuredSelection(tabItem.getData(KEY_RENDERING)));
- }
- handleTabActivated(tabItem);
- }
- else {
- tabFolder = createTabFolder(fRenderingsComposite);
- tabFolder.addSelectionListener(new SelectionListener() {
- public void widgetDefaultSelected(SelectionEvent e) {}
- public void widgetSelected(SelectionEvent e) {
- CTabItem tabItem = (CTabItem)e.item;
- updateMemorySpaceControlSelection(tabItem);
- fGotoAddressBar.loadSavedExpressions(context, fGotoMemorySpaceControl.isVisible() ? fGotoMemorySpaceControl.getText() : null);
- getSite().getSelectionProvider().setSelection(new StructuredSelection(tabItem.getData(KEY_RENDERING)));
- handleTabActivated(tabItem);
- }
- });
-
- tabFolder.setData(KEY_RETRIEVAL, retrieval);
- fContextFolders.put(retrieval, tabFolder);
- fStackLayout.topControl = tabFolder;
- }
- // update debug context to the new selection
- tabFolder.setData(KEY_CONTEXT, context);
-
-
- final CTabFolder activeFolder = tabFolder;
- if (!activeFolder.equals(tabFolder)) {
- return;
- }
-
- // Don't expose the memory spaces widget if there are none or
- // only one memory space involved.
- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=309032#c50
- if (memorySpaces.length >= 2) {
- fGotoMemorySpaceControl.setItems(memorySpaces);
-
- // Add the '----' (N/A) entry unless the retrieval object
- // says it requires a memory space ID in all cases
- boolean addNA = true;
- if (retrieval instanceof IMemorySpaceAwareMemoryBlockRetrieval) {
- addNA = !((IMemorySpaceAwareMemoryBlockRetrieval)retrieval).creatingBlockRequiresMemorySpaceID();
- }
- if (addNA) {
- fGotoMemorySpaceControl.add(NA_MEMORY_SPACE_ID, 0);
- }
- setMemorySpaceControlVisible(true);
- }
- else {
- fGotoMemorySpaceControl.setItems(new String[0]);
- setMemorySpaceControlVisible(false);
- }
-
- updateMemorySpaceControlSelection(activeFolder.getSelection());
- fGotoAddressBar.loadSavedExpressions(context, fGotoMemorySpaceControl.isVisible() ? fGotoMemorySpaceControl.getText() : null);
-
- fStackLayout.topControl.getParent().layout(true);
- }
- });
- }
-
- /**
- * Update the expression text in goto address widget to reflect the memory
- * rendering expression
- *
- * @param item
- * the active tab; may be null if in a "fresh" memory browser instance
- */
- protected void updateExpression(CTabItem activeFolder) {
- String expression = (activeFolder != null) ? (String) activeFolder.getData(KEY_EXPRESSION) : null;
- if (expression != null) {
- fGotoAddressBar.setExpressionText(expression);
- }
- }
-
- protected final void handleTabActivated(CTabItem item) {
- if (item != null) {
- updateActiveRendering((IMemoryRendering) item.getData(KEY_RENDERING));
- }
- }
-
- private void updateActiveRendering(IMemoryRendering rendering) {
- if (fActiveRendering == rendering) {
- return;
- }
- if (fActiveRendering != null) {
- fActiveRendering.deactivated();
- fActiveRendering.becomesHidden();
- }
- if (rendering != null) {
- rendering.activated();
- rendering.becomesVisible();
- }
- fActiveRendering = rendering;
- }
-
- private void setMemorySpaceControlVisible(boolean visible) {
- FormData data = (FormData)fGotoAddressBarControl.getLayoutData();
- if (visible) {
- data.left = new FormAttachment(fGotoMemorySpaceControl);
- }
- else {
- data.left = new FormAttachment(0);
- }
- fGotoMemorySpaceControl.setVisible(visible);
-
- }
-
- /**
- * Update the selection in the memory space combobox to reflect the memory
- * space being shown in the given tab
- *
- * @param item
- * the active tab; may be null if in a "fresh" memory browser instance
- */
- private void updateMemorySpaceControlSelection(CTabItem item) {
- String[] memorySpaces = fGotoMemorySpaceControl.getItems();
- if (memorySpaces.length > 0 ) {
- // Don't assume that the memory space previously set in the tab
- // is one of the ones now available. If it isn't, then select
- // the first available one and update the tab data
- boolean foundIt = false;
- if (item != null) {
- String currentMemorySpace = (String) item.getData(KEY_MEMORY_SPACE);
- if (currentMemorySpace != null) {
- assert currentMemorySpace.length() > 0;
- for (String memorySpace : memorySpaces) {
- if (memorySpace.equals(currentMemorySpace)) {
- foundIt = true;
- fGotoMemorySpaceControl.setText(currentMemorySpace);
- break;
- }
- }
- }
- }
- if (!foundIt) {
- fGotoMemorySpaceControl.select(0);
- if (item != null) {
- item.setData(KEY_MEMORY_SPACE, null);
- }
- }
- fGotoMemorySpaceControl.setVisible(true);
- }
- else {
- fGotoMemorySpaceControl.setVisible(false);
- }
- fGotoMemorySpaceControl.getParent().layout(true);
-
- }
-
- private String getDefaultRenderingTypeId()
- {
- return defaultRenderingTypeId;
- }
-
- public void setDefaultRenderingTypeId(String id)
- {
- defaultRenderingTypeId = id;
- IPreferenceStore store = MemoryBrowserPlugin.getDefault().getPreferenceStore();
- store.setValue(PREF_DEFAULT_RENDERING, defaultRenderingTypeId);
- }
-
- /**
- * Populate given tab with a rendering positioned at specified expression and memory space.
- * Will create a new rendering if one does not exist for the given memory space
- *
- * @param tab item to populate
- * @param retrieval memory service to retrieve memory block from
- * @param context memory block would be retrieved
- * @param memorySpaceId of the expression or null if not supported
- * @param expression from where to retrieve the memory block
- * @return return the memory rendering or null if could not be created
- *
- * @throws DebugException if could not retrieve memory block (e.g. invalid expression)
- */
- private IMemoryRendering populateTabWithRendering(final CTabItem tab, final IMemoryBlockRetrieval retrieval, Object context, String memorySpaceId, String expression) throws DebugException {
- IMemoryRenderingType type = DebugUITools.getMemoryRenderingManager().getRenderingType(getDefaultRenderingTypeId());
- IMemoryRenderingContainer container = (IMemoryRenderingContainer)tab.getData(KEY_CONTAINER);
- if (container == null) {
- container = new MemoryBrowserRenderingContainer();
- fCurrentContainers.add(container);
- }
-
- IMemoryRendering rendering = getRenderings(tab).get(memorySpaceId);
- if (rendering == null) {
- // No rendering yet. Create rendering and associated memory block.
- // createMemoryBlock will throw if expression cannot be resolved
- IMemoryBlockExtension block = createMemoryBlock(retrieval, expression, context, memorySpaceId);
- try {
- rendering = type.createRendering();
- } catch (CoreException e) {
- MemoryBrowserPlugin.getDefault().getLog().log(new Status(Status.ERROR, MemoryBrowserPlugin.PLUGIN_ID, "", e)); //$NON-NLS-1$
- return null;
- }
-
- rendering.init(container, block);
- container.addMemoryRendering(rendering);
- rendering.createControl(tab.getParent());
- getRenderings(tab).put(memorySpaceId, rendering);
- getMemoryBlocks(tab).add(block);
- rendering.addPropertyChangeListener(new RenderingPropertyChangeListener(tab, rendering));
- }
-
- tab.setControl(rendering.getControl());
- tab.getParent().setSelection(0);
- tab.setData(KEY_RENDERING, rendering);
- tab.setData(KEY_MEMORY_SPACE, memorySpaceId);
- tab.setData(KEY_CONTAINER, container);
- tab.setData(KEY_RENDERING_TYPE, type);
- tab.setData(KEY_EXPRESSION, expression);
- tab.setData(KEY_EXPRESSION_ADDRESS, ((IMemoryBlockExtension)rendering.getMemoryBlock()).getBigBaseAddress());
- getSite().getSelectionProvider().setSelection(new StructuredSelection(tab.getData(KEY_RENDERING)));
-
- return rendering;
- }
-
-
- private void releaseTabFolder(final IMemoryBlockRetrieval retrieval)
- {
- final CTabFolder folder = fContextFolders.get(retrieval);
- if(folder != null)
- {
- Runnable run = new Runnable() {
- public void run() {
- for(CTabItem tab : folder.getItems()) {
- disposeTab(tab);
- }
- fContextFolders.remove(retrieval);
- folder.dispose();
-
- if (fStackLayout.topControl.equals(folder)) {
- handleUnsupportedSelection();
- }
- }
- };
- runOnUIThread(run);
- }
- }
-
- class SelectionProviderAdapter implements ISelectionProvider {
-
- List<ISelectionChangedListener> listeners = new ArrayList<ISelectionChangedListener>();
-
- ISelection theSelection = StructuredSelection.EMPTY;
-
- public void addSelectionChangedListener(ISelectionChangedListener listener) {
- listeners.add(listener);
- }
-
- public ISelection getSelection() {
- return theSelection;
- }
-
- public void removeSelectionChangedListener(
- ISelectionChangedListener listener) {
- listeners.remove(listener);
- }
-
- public void setSelection(ISelection selection) {
- theSelection = selection;
- final SelectionChangedEvent e = new SelectionChangedEvent(this, selection);
- Object[] listenersArray = listeners.toArray();
-
- for (int i = 0; i < listenersArray.length; i++) {
- final ISelectionChangedListener l = (ISelectionChangedListener) listenersArray[i];
- SafeRunner.run(new SafeRunnable() {
- public void run() {
- l.selectionChanged(e);
- }
- });
- }
- }
- }
-
- /**
- * create a memory block
- * @param retrieval memory block retrieval.
- * @param expression expression to be evaluated to an addressL
- * @param context context for evaluating the expression. This is typically
- * a debug element.
- * @param memorySpaceID a memory space identifier, or null if n/a
- * @return a memory block based on the given expression and context
- * @throws DebugException if unable to retrieve the specified memory
- */
- private IMemoryBlockExtension createMemoryBlock(IMemoryBlockRetrieval retrieval, String expression, Object context, String memorySpaceID) throws DebugException {
- IMemoryBlockExtension block = null;
- IMemoryBlockRetrievalExtension retrievalExtension = null;
- if (retrieval instanceof IMemoryBlockRetrievalExtension) {
- retrievalExtension = (IMemoryBlockRetrievalExtension) retrieval;
- } else if(retrieval instanceof IAdaptable) {
- retrievalExtension = (IMemoryBlockRetrievalExtension)((IAdaptable) retrieval).getAdapter(IMemoryBlockRetrievalExtension.class);
- }
- if (retrievalExtension != null) {
- if (retrievalExtension instanceof IMemorySpaceAwareMemoryBlockRetrieval) {
- block = ((IMemorySpaceAwareMemoryBlockRetrieval)retrievalExtension).getMemoryBlock(expression, context, memorySpaceID);
- }
- else {
- block = retrievalExtension.getExtendedMemoryBlock(expression, context);
- }
- }
- if ( block == null ) {
- throw new DebugException(new Status(Status.ERROR, MemoryBrowserPlugin.PLUGIN_ID, "Extended Memory Block could not be obtained")); //$NON-NLS-1$
- }
- return block;
- }
-
- /**
- * Get a memory address for an expression in a given context.
- * @param retrieval
- * @param expression
- * @param context
- * @return BigInteger address of the expression
- * @throws DebugException
- */
- private BigInteger getExpressionAddress(IMemoryBlockRetrieval retrieval, String expression, Object context, String memorySpaceId) throws DebugException {
- // Until 257842 issue is solved this is done via IMemoryBlockRetrievalExtension API.
- IMemoryBlockExtension newBlock = createMemoryBlock(retrieval, expression, context, memorySpaceId);
- BigInteger address = newBlock.getBigBaseAddress();
- newBlock.dispose();
- return address;
- }
-
- /**
- * Execute runnable on UI thread if the current thread is not an UI thread.
- * Otherwise execute it directly.
- *
- * @param runnable
- * the runnable to execute
- */
- private void runOnUIThread(final Runnable runnable) {
- if (Display.getCurrent() != null) {
- runnable.run();
- }
- else {
- UIJob job = new UIJob("Memory Browser UI Job"){ //$NON-NLS-1$
- @Override
- public IStatus runInUIThread(IProgressMonitor monitor) {
- runnable.run();
- return Status.OK_STATUS;
- }};
- job.setSystem(true);
- job.schedule();
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.cdt.debug.ui.memory.memorybrowser.api.IMemoryBrowser#go(java.lang.String, java.lang.String, boolean)
- */
- public void go(String expression, String memorySpaceId, boolean inNewTab)
- throws CoreException {
- if (expression == null) {
- throw new IllegalArgumentException("expression cannot be null");
- }
- expression = expression.trim();
- if (expression.length() == 0) {
- throw new IllegalArgumentException("expression cannot be empty");
- }
- if (!fGotoMemorySpaceControl.isDisposed() && fGotoMemorySpaceControl.isVisible()) {
- if (memorySpaceId == null) {
- // if caller passed null, use whatever memory space is selected in the control
- memorySpaceId = fGotoMemorySpaceControl.getText();
- if (memorySpaceId.equals(NA_MEMORY_SPACE_ID)) {
- memorySpaceId = null;
- }
- }
- else {
- // if caller passed empty string, it means n/a (same as "----" in the selector)
- memorySpaceId = memorySpaceId.trim();
- if (memorySpaceId.length() == 0) {
- memorySpaceId = null;
- }
- else {
- // Check that the ID requested by the user is a valid one
- if (fGotoMemorySpaceControl.indexOf(memorySpaceId) == -1) {
- throw new IllegalArgumentException("unrecognized memory space ID");
- }
- }
-
- fGotoMemorySpaceControl.setText(memorySpaceId == null ? NA_MEMORY_SPACE_ID : memorySpaceId);
- }
- }
-
- fGotoAddressBar.setExpressionText(expression);
- performGo(inNewTab, expression, memorySpaceId);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.cdt.debug.ui.memory.memorybrowser.api.IMemoryBrowser#getSelectedMemorySpace()
- */
- public String getSelectedMemorySpace() {
- if (!fGotoMemorySpaceControl.isDisposed() && fGotoMemorySpaceControl.isVisible()) {
- String id = fGotoMemorySpaceControl.getText();
- return id.equals(NA_MEMORY_SPACE_ID) ? null : id;
- }
- return null;
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2015 Wind River Systems, Inc. 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Ted R Williams (Mentor Graphics, Inc.) - address space enhancements + * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781) + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.memorybrowser; + +import java.lang.reflect.Type; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.debug.core.model.provisional.IMemoryRenderingViewportProvider; +import org.eclipse.cdt.debug.core.model.provisional.IMemorySpaceAwareMemoryBlockRetrieval; +import org.eclipse.cdt.debug.internal.core.CRequest; +import org.eclipse.cdt.debug.ui.memory.memorybrowser.api.IMemoryBrowser; +import org.eclipse.cdt.debug.ui.provisional.IRepositionableMemoryRendering2; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IMemoryBlockExtension; +import org.eclipse.debug.core.model.IMemoryBlockRetrieval; +import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension; +import org.eclipse.debug.core.model.MemoryByte; +import org.eclipse.debug.internal.ui.memory.MemoryRenderingManager; +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.debug.ui.memory.IMemoryRendering; +import org.eclipse.debug.ui.memory.IMemoryRenderingContainer; +import org.eclipse.debug.ui.memory.IMemoryRenderingSite; +import org.eclipse.debug.ui.memory.IMemoryRenderingSynchronizationService; +import org.eclipse.debug.ui.memory.IMemoryRenderingType; +import org.eclipse.debug.ui.memory.IRepositionableMemoryRendering; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.ColorRegistry; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.IBasicPropertyConstants; +import org.eclipse.jface.viewers.ILabelDecorator; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabFolder2Adapter; +import org.eclipse.swt.custom.CTabFolderEvent; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.custom.StackLayout; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTarget; +import org.eclipse.swt.dnd.DropTargetAdapter; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPreferenceConstants; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.ViewPart; +import org.eclipse.ui.progress.UIJob; +import org.eclipse.ui.progress.WorkbenchJob; + +/** + * A lightweight rendering container. + * + * Debug model requirements: + * IMemoryBlockExtension (IMemoryBlock not supported) + * IMemoryBlockRetrievalExtension + * <p> + * Rendering requirements: + * IRepositionableMemoryRendering + * + */ + +@SuppressWarnings("restriction") /* Debug Platform's Flexible hierarchy is still provisional */ + +public class MemoryBrowser extends ViewPart implements IDebugContextListener, IMemoryRenderingSite, IDebugEventSetListener, IMemoryBrowser +{ + public static final String ID = "org.eclipse.cdt.debug.ui.memory.memorybrowser.MemoryBrowser"; //$NON-NLS-1$ + + protected StackLayout fStackLayout; + private Composite fRenderingsComposite; + private GoToAddressBarWidget fGotoAddressBar; + private DropTarget fDropTarget; + private Control fGotoAddressBarControl; + private Combo fGotoMemorySpaceControl; + private Label fUnsupportedLabel; + private Composite fMainComposite; + private String defaultRenderingTypeId = null; + private IMemoryRendering fActiveRendering; + + /** + * Every memory retrieval object is given its own tab folder. Typically all + * elements of a "process" (process, threads, frames) have the same + * retrieval object. + */ + private Map<IMemoryBlockRetrieval,CTabFolder> fContextFolders = new HashMap<IMemoryBlockRetrieval,CTabFolder> (); + + private List<IMemoryRenderingContainer> fCurrentContainers = new ArrayList<IMemoryRenderingContainer>(); + + private final static String KEY_CONTEXT = "CONTEXT"; //$NON-NLS-1$ + private final static String KEY_CONTAINER = "CONTAINER"; //$NON-NLS-1$ + private final static String KEY_RENDERING_TYPE = "RENDERING_TYPE"; //$NON-NLS-1$ + + /** + * Property we attach to a CTabItem to track the retrieval object we use to + * create memory blocks on the tab's behalf. Value is an + * {@link IMemoryBlockRetrieval} + */ + private final static String KEY_RETRIEVAL = "RETRIEVAL"; //$NON-NLS-1$ + + /** + * Property we attach to a CTabItem to track the memory space it's + * associated with. Value is a memory space ID (String), or null if n/a + */ + private final static String KEY_MEMORY_SPACE = "MEMORY_SPACE"; //$NON-NLS-1$ + + /** + * Property we attach to a CTabItem to track what renderings have been + * created on its behalf. There will be more than one rendering if the + * backend supports memory spaces, there is more than one such space, and + * the user has viewed memory in multiple memory spaces within that tab. + * The value is a map of memory-space-ID==>IMemoryRendering. + */ + private final static String KEY_RENDERINGS = "RENDERINGS"; //$NON-NLS-1$ + + /** + * Property we attach to a CTabItem to track the active rendering in the + * tab. The value is an IMemoryRendering. + */ + private final static String KEY_RENDERING = "RENDERING"; //$NON-NLS-1$ + + /** + * Property we attach to a CTabItem to track what memory blocks have been + * created on its behalf. There can be multiple when dealing with memory + * spaces, for the same reasons there can be multiple renderings. There is a + * 1:1:1 association between rendering, block and memory space. The value is + * a list of IMemoryBlockExtension + */ + private final static String KEY_MEMORY_BLOCKS = "MEMORY_BLOCKS"; //$NON-NLS-1$ + + /** + * Property we attach to a CTabItem to track the expression we used to + * create memory blocks on the tab's behalf. Value is a String. + */ + private final static String KEY_EXPRESSION = "EXPRESSION"; //$NON-NLS-1$ + + /** + * Property we attach to a CTabItem to track the address associated with + * KEY_EXPRESSION. Value is a BigInteger + */ + private final static String KEY_EXPRESSION_ADDRESS = "EXPRESSION_ADDRESS"; //$NON-NLS-1$ + + public static final String PREF_DEFAULT_RENDERING = "org.eclipse.cdt.debug.ui.memory.memorybrowser.defaultRendering"; //$NON-NLS-1$ + + /** + * The text we use in the combobox to represent no memory space specification + */ + private static final String NA_MEMORY_SPACE_ID = " -----"; //$NON-NLS-1$ + + public MemoryBrowser() { + } + + public Control getControl() { + return fMainComposite; + } + + /* + * Handles DnD from other views. + */ + private class MemoryDropAdapter extends DropTargetAdapter { + /* + * @see org.eclipse.swt.dnd.DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent) + */ + @Override + public void drop(final DropTargetEvent event) { + if (TextTransfer.getInstance().isSupportedType( event.currentDataType )) { + if ( event.data instanceof String ) { + fGotoAddressBar.setExpressionText( (String) event.data ); + performGo(false); + } + } + } + + /* + * @see org.eclipse.swt.dnd.DropTargetListener#dragEnter(org.eclipse.swt.dnd.DropTargetEvent) + */ + @Override + public void dragEnter(DropTargetEvent event) { + event.detail = DND.DROP_COPY; + event.feedback = DND.FEEDBACK_NONE; + } + } + + @Override + public void createPartControl(Composite parent) { + // set default rendering type. use the traditional rendering if available. fallback on first registered type. + // this should eventually be configurable via a preference page. + boolean isDefaultRenderingAvailable = false; + IPreferenceStore store = MemoryBrowserPlugin.getDefault().getPreferenceStore(); + String defaultRendering = store.getString(PREF_DEFAULT_RENDERING); + if(defaultRendering == null || defaultRendering.trim().length() == 0) + { + defaultRendering = "org.eclipse.cdt.debug.ui.memory.traditional.TraditionalRendering"; //$NON-NLS-1$ + } + + IMemoryRenderingType[] types = getRenderingTypes(); + for(final IMemoryRenderingType type : types) + { + if(type.getId().equals(defaultRendering)) + { + isDefaultRenderingAvailable = true; + break; + } + } + if(isDefaultRenderingAvailable) + defaultRenderingTypeId = defaultRendering; + else if(types.length > 0) + defaultRenderingTypeId = types[0].getId(); + + getSite().setSelectionProvider(new SelectionProviderAdapter()); + + fMainComposite = new Composite(parent, SWT.NONE); + + FormLayout layout = new FormLayout(); + layout.spacing = 0; + fMainComposite.setLayout(layout); + + fGotoMemorySpaceControl = new Combo(fMainComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + fGotoAddressBar = new GoToAddressBarWidget(); + fGotoAddressBarControl = fGotoAddressBar.createControl(fMainComposite); + + if (fDropTarget == null) { + fDropTarget = new DropTarget(fGotoAddressBarControl, DND.DROP_COPY | DND.DROP_DEFAULT); + fDropTarget.setTransfer( new Transfer[] { TextTransfer.getInstance() }); + fDropTarget.addDropListener(new MemoryDropAdapter()); + } + + fGotoAddressBar.getButton(IDialogConstants.OK_ID).addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + performGo(false); + } + }); + + fGotoAddressBar.getButton(GoToAddressBarWidget.ID_GO_NEW_TAB).addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + performGo(true); + } + }); + + fGotoAddressBar.getExpressionWidget().addSelectionListener(new SelectionAdapter() { + @Override + public void widgetDefaultSelected(SelectionEvent e) { + performGo(false); + } + @Override + public void widgetSelected(SelectionEvent e) { + performGo(false); + } + }); + + fGotoMemorySpaceControl.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if(fGotoMemorySpaceControl.getItemCount() >= 2) { + final CTabFolder activeFolder = (CTabFolder) fStackLayout.topControl; + if (activeFolder != null) { + final Object context = activeFolder.getData(KEY_CONTEXT); + fGotoAddressBar.loadSavedExpressions(context, fGotoMemorySpaceControl.getText()); + performGo(false); + } + } + } + }); + + + FormData data = new FormData(); + data.top = new FormAttachment(0); + data.left = new FormAttachment(fGotoMemorySpaceControl); + data.right = new FormAttachment(100); + fGotoAddressBarControl.setLayoutData(data); + + fRenderingsComposite = new Composite(fMainComposite, SWT.NONE); + data = new FormData(); + data.top = new FormAttachment(fGotoAddressBarControl); + data.left = new FormAttachment(0); + data.right = new FormAttachment(100); + data.bottom = new FormAttachment(100); + fRenderingsComposite.setLayoutData(data); + + fStackLayout = new StackLayout(); + + fRenderingsComposite.setLayout(fStackLayout); + + fUnsupportedLabel = new Label(fRenderingsComposite, SWT.NONE); + fUnsupportedLabel.setText(""); //$NON-NLS-1$ + + handleUnsupportedSelection(); + + PlatformUI.getWorkbench().getHelpSystem().setHelp(fMainComposite, MemoryBrowserPlugin.PLUGIN_ID); + makeActions(); + hookContextMenu(); + contributeToActionBars(); + + Object selection = null; + IDebugContextService contextService = + DebugUITools.getDebugContextManager().getContextService(getSite().getWorkbenchWindow()); + if (isBug145635Patched()) { + String presentationContextId = getPresentationContextId(); + contextService.addDebugContextListener(this, presentationContextId); + selection = contextService.getActiveContext(presentationContextId); + } else { + DebugUITools.addPartDebugContextListener(getSite(), this); + selection = contextService.getActiveContext(getSite().getId(), ((IViewSite)getSite()).getSecondaryId()); + } + + DebugPlugin.getDefault().addDebugEventListener(this); + + if(selection instanceof StructuredSelection) + handleDebugContextChanged(((StructuredSelection) selection).getFirstElement()); + } + + private boolean isBug145635Patched() { + Type[] managerTypes = DebugUITools.getDebugContextManager().getClass().getGenericInterfaces(); + for (int i = 0; i < managerTypes.length; i++) { + if (managerTypes[i] instanceof Class<?>) { + Class<?> clazz = (Class<?>)managerTypes[i]; + if ("org.eclipse.debug.ui.contexts.IBug145635Marker".equals(clazz.getName()) ) { //$NON-NLS-1$ + return true; + } + } + } + return false; + } + + /** + * Clears the expression history for the active tab + */ + public void clearExpressionHistoryForActiveTab() { + final CTabFolder activeFolder = (CTabFolder) fStackLayout.topControl; + if (activeFolder != null) { + final Object context = activeFolder.getData(KEY_CONTEXT); + fGotoAddressBar.clearExpressionHistory(context); + } + } + + /** + * Returns the presentation context id for this view. Used to support the + * pin and clone feature patch from bug 145635. + * + * @return context id + */ + private String getPresentationContextId() { + IViewSite site = (IViewSite)getSite(); + return site.getId() + (site.getSecondaryId() != null ? (":" + site.getSecondaryId()) : ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + @Override + public void dispose() { + if (fDropTarget != null) { + fDropTarget.dispose(); + fDropTarget = null; + } + DebugPlugin.getDefault().removeDebugEventListener(this); + IDebugContextService contextService = + DebugUITools.getDebugContextManager().getContextService(getSite().getWorkbenchWindow()); + if (isBug145635Patched()) { + String presentationContextId = getPresentationContextId(); + contextService.removeDebugContextListener(this, presentationContextId); + } else { + DebugUITools.removePartDebugContextListener(getSite(), this); + } + super.dispose(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[]) + */ + public void handleDebugEvents(DebugEvent[] events) { + for (DebugEvent event: events) { + Object source = event.getSource(); + if (event.getKind() == DebugEvent.TERMINATE && source instanceof IMemoryBlockRetrieval) { + releaseTabFolder((IMemoryBlockRetrieval)source); + } + } + } + + public IMemoryRenderingContainer getContainer(String id) { + return null; + } + + public IMemoryRenderingContainer[] getMemoryRenderingContainers() { + IMemoryRenderingContainer[] containerList = new IMemoryRenderingContainer[fCurrentContainers.size()]; + for ( int idx = 0 ; idx < fCurrentContainers.size() ; idx ++ ) { + containerList[ idx ] = fCurrentContainers.get( idx ); + } + return containerList; + } + + public IMemoryRenderingSynchronizationService getSynchronizationService() { + return null; + } + + private void handleUnsupportedSelection() { + fStackLayout.topControl = fUnsupportedLabel; + if(!fGotoAddressBarControl.isDisposed()) { + fGotoAddressBarControl.setVisible(false); + } + if(!fGotoMemorySpaceControl.isDisposed()) { + fGotoMemorySpaceControl.setVisible(false); + } + } + + private void performGo(boolean inNewTab) { + // Index zero is the 'auto' (n/a) memory space entry, unless the backend + // said we need to force a memory space selection + String memorySpace = null; + if (fGotoMemorySpaceControl.isVisible()) { + memorySpace = fGotoMemorySpaceControl.getText(); + if (memorySpace.equals(NA_MEMORY_SPACE_ID)) { + memorySpace = null; + } + assert (memorySpace == null) || (memorySpace.length() > 0); + } + + String expression = fGotoAddressBar.getExpressionText(); + if (expression.length() > 0) { + final CTabFolder activeFolder = (CTabFolder) fStackLayout.topControl; + Object context = null; + if (activeFolder != null) { + context = activeFolder.getData(KEY_CONTEXT); + } + fGotoAddressBar.addExpressionToHistory(context, expression, memorySpace); + performGo(inNewTab, expression, memorySpace); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.ui.memory.memorybrowser.api.IMemoryBrowser#getActiveRetrieval() + */ + public IMemoryBlockRetrieval getActiveRetrieval() { + final CTabFolder activeFolder = (CTabFolder) fStackLayout.topControl; + if (activeFolder == null) + return null; + + return (IMemoryBlockRetrieval) activeFolder.getData(KEY_RETRIEVAL); + } + + public void performGo(boolean inNewTab, final String expression, final String memorySpaceId) { + final CTabFolder activeFolder = (CTabFolder) fStackLayout.topControl; + if (activeFolder != null) { + final IMemoryBlockRetrieval retrieval = (IMemoryBlockRetrieval) activeFolder.getData(KEY_RETRIEVAL); + final Object context = activeFolder.getData(KEY_CONTEXT); + IMemoryRendering rendering = null; + + CTabItem item = activeFolder.getSelection(); + if (inNewTab || item == null) + { + try { + item = createTab(activeFolder, activeFolder.getSelectionIndex() + 1); + rendering = populateTabWithRendering(item, retrieval, context, memorySpaceId, expression); + fContextFolders.put(retrieval, activeFolder); + activeFolder.setSelection(item); + getSite().getSelectionProvider().setSelection(new StructuredSelection(item.getData(KEY_RENDERING))); + handleTabActivated(item); + } catch (DebugException e1) { + fGotoAddressBar.handleExpressionStatus(new Status(Status.ERROR, MemoryBrowserPlugin.PLUGIN_ID, + Messages.getString("MemoryBrowser.FailedToGoToAddressTitle"), e1)); //$NON-NLS-1$ + if (item != null) { + item.dispose(); + } + return; + } + } else { + // Tab is already in place. However, the user may have selected + // a different memory space. If so, that requires us to switch + // out the rendering in the tab with either a new one or an + // existing one already associated with that memory space. + String oldMemorySpaceId = (String)activeFolder.getSelection().getData(KEY_MEMORY_SPACE); + assert oldMemorySpaceId == null || !oldMemorySpaceId.equals(NA_MEMORY_SPACE_ID) : "should be null reference or an explicit, valid memory space ID (not including '----')"; //$NON-NLS-1$ + if ((oldMemorySpaceId != null && !oldMemorySpaceId.equals(memorySpaceId)) + || (oldMemorySpaceId == null && memorySpaceId != null)) { + try { + rendering = populateTabWithRendering(item, retrieval, context, memorySpaceId, expression); + activeFolder.setSelection(item); + getSite().getSelectionProvider().setSelection(new StructuredSelection(item.getData(KEY_RENDERING))); + handleTabActivated(item); + } catch (DebugException e) { + fGotoAddressBar.handleExpressionStatus(new Status(Status.ERROR, MemoryBrowserPlugin.PLUGIN_ID, + Messages.getString("MemoryBrowser.FailedToGoToAddressTitle"), e)); //$NON-NLS-1$ + return; + } + } + } + + if (rendering == null) { + rendering = (IRepositionableMemoryRendering) activeFolder.getSelection().getData(KEY_RENDERING); + } + + if (retrieval instanceof IMemoryBlockRetrievalExtension && + rendering instanceof IRepositionableMemoryRendering) { + final IRepositionableMemoryRendering renderingFinal = (IRepositionableMemoryRendering) rendering; + new Thread() { + @Override + public void run() { + try { + final BigInteger newBase = getExpressionAddress(retrieval, expression, context, memorySpaceId); + IMemoryBlockExtension block = (IMemoryBlockExtension) renderingFinal.getMemoryBlock(); + if (block.supportBaseAddressModification()) { + block.setBaseAddress(newBase); + } + if(renderingFinal instanceof IRepositionableMemoryRendering2) { + ((IRepositionableMemoryRendering2)renderingFinal).goToAddress(newBase, expression); + } + else { + renderingFinal.goToAddress(newBase); + } + + runOnUIThread(new Runnable(){ + public void run() { + CTabItem selection = activeFolder.getSelection(); + selection.setData(KEY_EXPRESSION, expression); + selection.setData(KEY_EXPRESSION_ADDRESS, newBase); + fGotoAddressBar.handleExpressionStatus(Status.OK_STATUS); + updateLabel(selection, renderingFinal); + } + }); + } catch (final DebugException e1) { + // widgets update require Display + runOnUIThread(new Runnable(){ + public void run() { + fGotoAddressBar.handleExpressionStatus(new Status(Status.ERROR, MemoryBrowserPlugin.PLUGIN_ID, + Messages.getString("MemoryBrowser.FailedToGoToAddressTitle"), e1)); //$NON-NLS-1$ + } + }); + } + } + }.start(); + } + } + } + + private void updateLabel(CTabItem tab, IMemoryRendering rendering) { + // The default is to use the label provided by the base rendering + // interface. + String label = rendering.getLabel(); + + // If the rendering provides access to its viewport address (the first + // address shown in the rendering, subject to scrolling), display that + // in the tab rather than the expression that was used when the tab was + // first created. + if (rendering instanceof IMemoryRenderingViewportProvider) { + BigInteger viewportAddress = ((IMemoryRenderingViewportProvider)rendering).getViewportAddress(); + + // The base label generation puts the rendering type name in "<>" and + // appends it to the label. Fish that out + String renderingType = null; + int i = label.indexOf('<'); + if (i >= 0) { + renderingType = label.substring(i); + } + + label = null; + + // If a memory space is involved, we want to include its ID in the label + String memorySpaceID = (String)tab.getData(KEY_MEMORY_SPACE); + if (memorySpaceID != null) { + IMemoryBlockRetrieval retrieval = (IMemoryBlockRetrieval) tab.getParent().getData(KEY_RETRIEVAL); + if (retrieval instanceof IMemorySpaceAwareMemoryBlockRetrieval) { + label = ((IMemorySpaceAwareMemoryBlockRetrieval)retrieval).encodeAddress("0x" + viewportAddress.toString(16), memorySpaceID); + } + } + if (label == null) { + label = "0x" + viewportAddress.toString(16); + } + + // If the expression that was went to ("Go") is not a hex address, + // or it is but the user has scrolled/paged, then show the + // expression after the viewport hex address. Additionally, if some + // scrolling/paging has moved the viewport, also show the relative + // displacement. E.g., + // "0x10020 - gSomeVar(+20) <Traditional>" + // (for a tab where the user did a "Go" to "gSomeVar" then paged + // down, and where gSomeVar is at 0x10000) + // + String expression = (String)tab.getData(KEY_EXPRESSION); + BigInteger evaluatedAddress = (BigInteger)tab.getData(KEY_EXPRESSION_ADDRESS); + if(expression != null && !expression.equals("0x" + viewportAddress.toString(16))) { + label += " - " + expression; + BigInteger delta = evaluatedAddress.subtract(viewportAddress); + if (!delta.equals(BigInteger.ZERO)) { + label += "("; + label += delta.signum() < 0 ? '+' : '-'; + label += "0x" + delta.abs().toString(16) +")"; + } + } + + label += ' ' + renderingType;; + + // Allow the memory block to customize the label. The platform's + // Memory view support this (it was done in the call to + // rendering.getLabel() above) + IMemoryBlock block = rendering.getMemoryBlock(); + ILabelDecorator labelDec = (ILabelDecorator)block.getAdapter(ILabelDecorator.class); + if (labelDec != null) { + String newLabel = labelDec.decorateText(label, rendering); + if (newLabel != null) { + label = newLabel; + } + } + } + + tab.setText(label); + } + + private CTabFolder createTabFolder(Composite parent) + { + final CTabFolder folder = new CTabFolder(parent, SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM | SWT.FLAT); + + ColorRegistry reg = JFaceResources.getColorRegistry(); + Color c1 = reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_BG_START"), //$NON-NLS-1$ + c2 = reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_BG_END"); //$NON-NLS-1$ + folder.setSelectionBackground(new Color[] {c1, c2}, new int[] {100}, true); + folder.setSelectionForeground(reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_TEXT_COLOR")); //$NON-NLS-1$ + folder.setSimple(PlatformUI.getPreferenceStore().getBoolean(IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS)); + folder.setBorderVisible(true); + + // listener to dispose rendering resources for each closed tab + folder.addCTabFolder2Listener(new CTabFolder2Adapter() { + @Override + public void close(CTabFolderEvent event) { + event.doit = true; + CTabItem item = (CTabItem) event.item; + disposeTab(item); + } + }); + + // listener to dispose rendering resources for all tab items when view part is closed + folder.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + for(CTabItem tab : folder.getItems()) { + disposeTab(tab); + } + folder.removeDisposeListener(this); + } + }); + return folder; + } + + // these utility methods allow us restrict the scope of the unavoidable @SuppressWarnings + + @SuppressWarnings("unchecked") + private static Map<String, IMemoryRendering> getRenderings(CTabItem tabItem) { + return (Map<String, IMemoryRendering>)tabItem.getData(KEY_RENDERINGS); + } + + @SuppressWarnings("unchecked") + private static List<IMemoryBlockExtension> getMemoryBlocks(CTabItem tabItem) { + return (List<IMemoryBlockExtension>)tabItem.getData(KEY_MEMORY_BLOCKS); + } + + + /** + * dispose rendering resources associated with the tab item + * @param item + */ + private void disposeTab(CTabItem item ) { + if (item.isDisposed()) + return; + + IMemoryRenderingContainer container = (IMemoryRenderingContainer) item.getData(KEY_CONTAINER); + fCurrentContainers.remove( container ); + Map<String, IMemoryRendering> map = getRenderings(item); + Collection<IMemoryRendering> renderings = map.values(); + for (IMemoryRendering rendering : renderings) { + // always deactivate rendering before disposing it. + rendering.deactivated(); + rendering.dispose(); + if (rendering == fActiveRendering) { + fActiveRendering = null; + getSite().getSelectionProvider().setSelection(new StructuredSelection()); + } + } + map.clear(); + + List<IMemoryBlockExtension> blocks = getMemoryBlocks(item); + for (IMemoryBlockExtension block : blocks) { + try { + block.dispose(); + } catch (DebugException e) { + MemoryBrowserPlugin.getDefault().getLog().log(new Status(Status.ERROR, MemoryBrowserPlugin.PLUGIN_ID, "Could not dispose memory block", e)); //$NON-NLS-1$ + } + } + blocks.clear(); + } + + private CTabItem createTab(CTabFolder tabFolder, int index) { + int swtStyle = SWT.CLOSE; + CTabItem tab = new CTabItem(tabFolder, swtStyle, index); + tab.setData(KEY_RENDERINGS, new HashMap<String, IMemoryRendering>()); + tab.setData(KEY_MEMORY_BLOCKS, new ArrayList<IMemoryBlock>()); + return tab; + } + + private void hookContextMenu() { + MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + MemoryBrowser.this.fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(getControl()); + getControl().setMenu(menu); + } + + private void contributeToActionBars() { + IActionBars bars = getViewSite().getActionBars(); + fillLocalPullDown(bars.getMenuManager()); + fillLocalToolBar(bars.getToolBarManager()); + } + + private void fillLocalPullDown(IMenuManager manager) { + + + MenuManager sub = new MenuManager(Messages.getString("MemoryBrowser.DefaultRendering")); //$NON-NLS-1$ + + for(final IMemoryRenderingType type : getRenderingTypes()) + { + final Action action = new Action( + type.getLabel(), IAction.AS_RADIO_BUTTON) + { + @Override + public void run() + { + setDefaultRenderingTypeId(type.getId()); + } + }; + action.setChecked(type.getId().equals(getDefaultRenderingTypeId())); + sub.add(action); + } + + manager.add(sub); + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + + private void fillContextMenu(IMenuManager manager) { + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + + private void fillLocalToolBar(IToolBarManager manager) { + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + + private void makeActions() { + + } + + private IMemoryRenderingType[] getRenderingTypes() + { + return MemoryRenderingManager.getDefault().getRenderingTypes(new IMemoryBlockExtension(){ + public void connect(Object client) {} + public void disconnect(Object client) {} + public void dispose() throws DebugException {} + public int getAddressSize() throws DebugException { return 0; } + public int getAddressableSize() throws DebugException { return 0; } + public BigInteger getBigBaseAddress() throws DebugException { return null; } + public BigInteger getBigLength() throws DebugException { return null; } + public MemoryByte[] getBytesFromAddress(BigInteger address, long units) throws DebugException { return null; } + public MemoryByte[] getBytesFromOffset(BigInteger unitOffset, long addressableUnits) throws DebugException { return null; } + public Object[] getConnections() { return null; } + public String getExpression() { return null; } + public BigInteger getMemoryBlockEndAddress() throws DebugException { return null; } + public IMemoryBlockRetrieval getMemoryBlockRetrieval() { return null; } + public BigInteger getMemoryBlockStartAddress() throws DebugException { return null; } + public void setBaseAddress(BigInteger address) throws DebugException {} + public void setValue(BigInteger offset, byte[] bytes) throws DebugException {} + public boolean supportBaseAddressModification() throws DebugException { return false; } + public boolean supportsChangeManagement() { return false; } + public byte[] getBytes() throws DebugException { return null; } + public long getLength() { return 0; } + public long getStartAddress() { return 0; } + public void setValue(long offset, byte[] bytes) throws DebugException {} + public boolean supportsValueModification() { return false; } + public IDebugTarget getDebugTarget() { return null; } + public ILaunch getLaunch() { return null; } + public String getModelIdentifier() { return null; } + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Object getAdapter(Class adapter) { return null; } + }); + } + + @Override + public void setFocus() { + getControl().setFocus(); + } + + public void debugContextChanged(DebugContextEvent event) { + handleDebugContextChanged(((StructuredSelection) event.getContext()).getFirstElement()); + } + + private final class MemoryBrowserRenderingContainer implements + IMemoryRenderingContainer { + private final List<IMemoryRendering> renderings = new ArrayList<IMemoryRendering>(); + + private MemoryBrowserRenderingContainer() { + } + + public void addMemoryRendering(IMemoryRendering rendering) { + // do not allow duplicated objects + if (!renderings.contains(rendering)) { + renderings.add(rendering); + } + } + + public IMemoryRendering getActiveRendering() { + return renderings.isEmpty() ? null : renderings.get(renderings.size() -1); + } + + public String getId() { + return ID; + } + + public String getLabel() { + IMemoryRendering rendering = getActiveRendering(); + return rendering != null ? rendering.getLabel() : null; + } + + public IMemoryRenderingSite getMemoryRenderingSite() { + return MemoryBrowser.this; + } + + public IMemoryRendering[] getRenderings() { + return renderings.toArray(new IMemoryRendering[renderings.size()]); + } + + public void removeMemoryRendering(IMemoryRendering rendering) { + renderings.remove(rendering); + } + } + + private final class RenderingPropertyChangeListener implements + IPropertyChangeListener { + private final CTabItem tab; + private final IMemoryRendering newRendering; + + private RenderingPropertyChangeListener(CTabItem tab, + IMemoryRendering newRendering) { + this.tab = tab; + this.newRendering = newRendering; + } + + public void propertyChange(final PropertyChangeEvent event) { + WorkbenchJob job = new WorkbenchJob("MemoryBrowser PropertyChanged") { //$NON-NLS-1$ + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + if(tab.isDisposed()) + return Status.OK_STATUS; + + if (event.getProperty().equals(IBasicPropertyConstants.P_TEXT)) + updateLabel(tab, newRendering); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + job.schedule(); + } + } + + private class GetMemorySpacesRequest extends CRequest implements IMemorySpaceAwareMemoryBlockRetrieval.GetMemorySpacesRequest { + String [] fMemorySpaces; + public String[] getMemorySpaces() { + return fMemorySpaces; + } + public void setMemorySpaces(String[] memorySpaceIds) { + fMemorySpaces = memorySpaceIds; + } + } + + public void handleDebugContextChanged(final Object context) { + if(defaultRenderingTypeId == null) + return; + + IAdaptable adaptable = null; + IMemoryBlockRetrieval retrieval = null; + ILaunch launch = null; + + if(context instanceof IAdaptable) + { + adaptable = (IAdaptable) context; + retrieval = ((IMemoryBlockRetrieval) adaptable.getAdapter(IMemoryBlockRetrieval.class)); + launch = ((ILaunch) adaptable.getAdapter(ILaunch.class)); + } + + if(retrieval != null && launch != null && !launch.isTerminated()) { + if (retrieval instanceof IMemorySpaceAwareMemoryBlockRetrieval) { + final IMemoryBlockRetrieval _retrieval = retrieval; + ((IMemorySpaceAwareMemoryBlockRetrieval)retrieval).getMemorySpaces(context, new GetMemorySpacesRequest(){ + @Override + public void done() { + updateTab(_retrieval, context, isSuccess() ? getMemorySpaces() : new String[0]); + } + }); + } + else { + updateTab(retrieval, context, new String[0]); + } + } + else { + handleUnsupportedSelection(); + } + + fGotoMemorySpaceControl.pack(true); + fStackLayout.topControl.getParent().layout(true); + } + + /** + * Called to update the tab once the asynchronous query for memory spaces + * has returned a result. + * + * @param retrieval + * the retrieval object associated with the newly active debug + * context + * @param context + * the newly active context + * @param memorySpaces + * the memory spaces, if applicable. Otherwise an empty array. + */ + private void updateTab(final IMemoryBlockRetrieval retrieval, final Object context, final String[] memorySpaces) { + // GUI activity must be on the main thread + runOnUIThread(new Runnable(){ + public void run() { + if (fGotoAddressBarControl.isDisposed() || fGotoMemorySpaceControl.isDisposed()) { + return; + } + + fGotoAddressBarControl.setVisible(true); + + // If we've already created a tab folder for this retrieval + // object, bring it to the forefront. Otherwise create the + // folder. + CTabFolder tabFolder = fContextFolders.get(retrieval); + if(tabFolder != null) { + fStackLayout.topControl = tabFolder; + CTabItem tabItem = (CTabItem) tabFolder.getSelection(); + if ( tabItem != null ) { + getSite().getSelectionProvider().setSelection(new StructuredSelection(tabItem.getData(KEY_RENDERING))); + } + handleTabActivated(tabItem); + } + else { + tabFolder = createTabFolder(fRenderingsComposite); + tabFolder.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) {} + public void widgetSelected(SelectionEvent e) { + CTabItem tabItem = (CTabItem)e.item; + updateMemorySpaceControlSelection(tabItem); + fGotoAddressBar.loadSavedExpressions(context, fGotoMemorySpaceControl.isVisible() ? fGotoMemorySpaceControl.getText() : null); + getSite().getSelectionProvider().setSelection(new StructuredSelection(tabItem.getData(KEY_RENDERING))); + handleTabActivated(tabItem); + } + }); + + tabFolder.setData(KEY_RETRIEVAL, retrieval); + fContextFolders.put(retrieval, tabFolder); + fStackLayout.topControl = tabFolder; + } + // update debug context to the new selection + tabFolder.setData(KEY_CONTEXT, context); + + + final CTabFolder activeFolder = tabFolder; + if (!activeFolder.equals(tabFolder)) { + return; + } + + // Don't expose the memory spaces widget if there are none or + // only one memory space involved. + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=309032#c50 + if (memorySpaces.length >= 2) { + fGotoMemorySpaceControl.setItems(memorySpaces); + + // Add the '----' (N/A) entry unless the retrieval object + // says it requires a memory space ID in all cases + boolean addNA = true; + if (retrieval instanceof IMemorySpaceAwareMemoryBlockRetrieval) { + addNA = !((IMemorySpaceAwareMemoryBlockRetrieval)retrieval).creatingBlockRequiresMemorySpaceID(); + } + if (addNA) { + fGotoMemorySpaceControl.add(NA_MEMORY_SPACE_ID, 0); + } + setMemorySpaceControlVisible(true); + } + else { + fGotoMemorySpaceControl.setItems(new String[0]); + setMemorySpaceControlVisible(false); + } + + updateMemorySpaceControlSelection(activeFolder.getSelection()); + fGotoAddressBar.loadSavedExpressions(context, fGotoMemorySpaceControl.isVisible() ? fGotoMemorySpaceControl.getText() : null); + + fStackLayout.topControl.getParent().layout(true); + } + }); + } + + /** + * Update the expression text in goto address widget to reflect the memory + * rendering expression + * + * @param item + * the active tab; may be null if in a "fresh" memory browser instance + */ + protected void updateExpression(CTabItem activeFolder) { + String expression = (activeFolder != null) ? (String) activeFolder.getData(KEY_EXPRESSION) : null; + if (expression != null) { + fGotoAddressBar.setExpressionText(expression); + } + } + + protected final void handleTabActivated(CTabItem item) { + if (item != null) { + updateActiveRendering((IMemoryRendering) item.getData(KEY_RENDERING)); + } + } + + private void updateActiveRendering(IMemoryRendering rendering) { + if (fActiveRendering == rendering) { + return; + } + if (fActiveRendering != null) { + fActiveRendering.deactivated(); + fActiveRendering.becomesHidden(); + } + if (rendering != null) { + rendering.activated(); + rendering.becomesVisible(); + } + fActiveRendering = rendering; + } + + private void setMemorySpaceControlVisible(boolean visible) { + FormData data = (FormData)fGotoAddressBarControl.getLayoutData(); + if (visible) { + data.left = new FormAttachment(fGotoMemorySpaceControl); + } + else { + data.left = new FormAttachment(0); + } + fGotoMemorySpaceControl.setVisible(visible); + + } + + /** + * Update the selection in the memory space combobox to reflect the memory + * space being shown in the given tab + * + * @param item + * the active tab; may be null if in a "fresh" memory browser instance + */ + private void updateMemorySpaceControlSelection(CTabItem item) { + String[] memorySpaces = fGotoMemorySpaceControl.getItems(); + if (memorySpaces.length > 0 ) { + // Don't assume that the memory space previously set in the tab + // is one of the ones now available. If it isn't, then select + // the first available one and update the tab data + boolean foundIt = false; + if (item != null) { + String currentMemorySpace = (String) item.getData(KEY_MEMORY_SPACE); + if (currentMemorySpace != null) { + assert currentMemorySpace.length() > 0; + for (String memorySpace : memorySpaces) { + if (memorySpace.equals(currentMemorySpace)) { + foundIt = true; + fGotoMemorySpaceControl.setText(currentMemorySpace); + break; + } + } + } + } + if (!foundIt) { + fGotoMemorySpaceControl.select(0); + if (item != null) { + item.setData(KEY_MEMORY_SPACE, null); + } + } + fGotoMemorySpaceControl.setVisible(true); + } + else { + fGotoMemorySpaceControl.setVisible(false); + } + fGotoMemorySpaceControl.getParent().layout(true); + + } + + private String getDefaultRenderingTypeId() + { + return defaultRenderingTypeId; + } + + public void setDefaultRenderingTypeId(String id) + { + defaultRenderingTypeId = id; + IPreferenceStore store = MemoryBrowserPlugin.getDefault().getPreferenceStore(); + store.setValue(PREF_DEFAULT_RENDERING, defaultRenderingTypeId); + } + + /** + * Populate given tab with a rendering positioned at specified expression and memory space. + * Will create a new rendering if one does not exist for the given memory space + * + * @param tab item to populate + * @param retrieval memory service to retrieve memory block from + * @param context memory block would be retrieved + * @param memorySpaceId of the expression or null if not supported + * @param expression from where to retrieve the memory block + * @return return the memory rendering or null if could not be created + * + * @throws DebugException if could not retrieve memory block (e.g. invalid expression) + */ + private IMemoryRendering populateTabWithRendering(final CTabItem tab, final IMemoryBlockRetrieval retrieval, Object context, String memorySpaceId, String expression) throws DebugException { + IMemoryRenderingType type = DebugUITools.getMemoryRenderingManager().getRenderingType(getDefaultRenderingTypeId()); + IMemoryRenderingContainer container = (IMemoryRenderingContainer)tab.getData(KEY_CONTAINER); + if (container == null) { + container = new MemoryBrowserRenderingContainer(); + fCurrentContainers.add(container); + } + + IMemoryRendering rendering = getRenderings(tab).get(memorySpaceId); + if (rendering == null) { + // No rendering yet. Create rendering and associated memory block. + // createMemoryBlock will throw if expression cannot be resolved + IMemoryBlockExtension block = createMemoryBlock(retrieval, expression, context, memorySpaceId); + try { + rendering = type.createRendering(); + } catch (CoreException e) { + MemoryBrowserPlugin.getDefault().getLog().log(new Status(Status.ERROR, MemoryBrowserPlugin.PLUGIN_ID, "", e)); //$NON-NLS-1$ + return null; + } + + rendering.init(container, block); + container.addMemoryRendering(rendering); + rendering.createControl(tab.getParent()); + getRenderings(tab).put(memorySpaceId, rendering); + getMemoryBlocks(tab).add(block); + rendering.addPropertyChangeListener(new RenderingPropertyChangeListener(tab, rendering)); + } + + tab.setControl(rendering.getControl()); + tab.getParent().setSelection(0); + tab.setData(KEY_RENDERING, rendering); + tab.setData(KEY_MEMORY_SPACE, memorySpaceId); + tab.setData(KEY_CONTAINER, container); + tab.setData(KEY_RENDERING_TYPE, type); + tab.setData(KEY_EXPRESSION, expression); + tab.setData(KEY_EXPRESSION_ADDRESS, ((IMemoryBlockExtension)rendering.getMemoryBlock()).getBigBaseAddress()); + getSite().getSelectionProvider().setSelection(new StructuredSelection(tab.getData(KEY_RENDERING))); + + return rendering; + } + + + private void releaseTabFolder(final IMemoryBlockRetrieval retrieval) + { + final CTabFolder folder = fContextFolders.get(retrieval); + if(folder != null) + { + Runnable run = new Runnable() { + public void run() { + for(CTabItem tab : folder.getItems()) { + disposeTab(tab); + } + fContextFolders.remove(retrieval); + folder.dispose(); + + if (fStackLayout.topControl.equals(folder)) { + handleUnsupportedSelection(); + } + } + }; + runOnUIThread(run); + } + } + + class SelectionProviderAdapter implements ISelectionProvider { + + List<ISelectionChangedListener> listeners = new ArrayList<ISelectionChangedListener>(); + + ISelection theSelection = StructuredSelection.EMPTY; + + public void addSelectionChangedListener(ISelectionChangedListener listener) { + listeners.add(listener); + } + + public ISelection getSelection() { + return theSelection; + } + + public void removeSelectionChangedListener( + ISelectionChangedListener listener) { + listeners.remove(listener); + } + + public void setSelection(ISelection selection) { + theSelection = selection; + final SelectionChangedEvent e = new SelectionChangedEvent(this, selection); + Object[] listenersArray = listeners.toArray(); + + for (int i = 0; i < listenersArray.length; i++) { + final ISelectionChangedListener l = (ISelectionChangedListener) listenersArray[i]; + SafeRunner.run(new SafeRunnable() { + public void run() { + l.selectionChanged(e); + } + }); + } + } + } + + /** + * create a memory block + * @param retrieval memory block retrieval. + * @param expression expression to be evaluated to an addressL + * @param context context for evaluating the expression. This is typically + * a debug element. + * @param memorySpaceID a memory space identifier, or null if n/a + * @return a memory block based on the given expression and context + * @throws DebugException if unable to retrieve the specified memory + */ + private IMemoryBlockExtension createMemoryBlock(IMemoryBlockRetrieval retrieval, String expression, Object context, String memorySpaceID) throws DebugException { + IMemoryBlockExtension block = null; + IMemoryBlockRetrievalExtension retrievalExtension = null; + if (retrieval instanceof IMemoryBlockRetrievalExtension) { + retrievalExtension = (IMemoryBlockRetrievalExtension) retrieval; + } else if(retrieval instanceof IAdaptable) { + retrievalExtension = (IMemoryBlockRetrievalExtension)((IAdaptable) retrieval).getAdapter(IMemoryBlockRetrievalExtension.class); + } + if (retrievalExtension != null) { + if (retrievalExtension instanceof IMemorySpaceAwareMemoryBlockRetrieval) { + block = ((IMemorySpaceAwareMemoryBlockRetrieval)retrievalExtension).getMemoryBlock(expression, context, memorySpaceID); + } + else { + block = retrievalExtension.getExtendedMemoryBlock(expression, context); + } + } + if ( block == null ) { + throw new DebugException(new Status(Status.ERROR, MemoryBrowserPlugin.PLUGIN_ID, "Extended Memory Block could not be obtained")); //$NON-NLS-1$ + } + return block; + } + + /** + * Get a memory address for an expression in a given context. + * @param retrieval + * @param expression + * @param context + * @return BigInteger address of the expression + * @throws DebugException + */ + private BigInteger getExpressionAddress(IMemoryBlockRetrieval retrieval, String expression, Object context, String memorySpaceId) throws DebugException { + // Until 257842 issue is solved this is done via IMemoryBlockRetrievalExtension API. + IMemoryBlockExtension newBlock = createMemoryBlock(retrieval, expression, context, memorySpaceId); + BigInteger address = newBlock.getBigBaseAddress(); + newBlock.dispose(); + return address; + } + + /** + * Execute runnable on UI thread if the current thread is not an UI thread. + * Otherwise execute it directly. + * + * @param runnable + * the runnable to execute + */ + private void runOnUIThread(final Runnable runnable) { + if (Display.getCurrent() != null) { + runnable.run(); + } + else { + UIJob job = new UIJob("Memory Browser UI Job"){ //$NON-NLS-1$ + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + runnable.run(); + return Status.OK_STATUS; + }}; + job.setSystem(true); + job.schedule(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.ui.memory.memorybrowser.api.IMemoryBrowser#go(java.lang.String, java.lang.String, boolean) + */ + public void go(String expression, String memorySpaceId, boolean inNewTab) + throws CoreException { + if (expression == null) { + throw new IllegalArgumentException("expression cannot be null"); + } + expression = expression.trim(); + if (expression.length() == 0) { + throw new IllegalArgumentException("expression cannot be empty"); + } + if (!fGotoMemorySpaceControl.isDisposed() && fGotoMemorySpaceControl.isVisible()) { + if (memorySpaceId == null) { + // if caller passed null, use whatever memory space is selected in the control + memorySpaceId = fGotoMemorySpaceControl.getText(); + if (memorySpaceId.equals(NA_MEMORY_SPACE_ID)) { + memorySpaceId = null; + } + } + else { + // if caller passed empty string, it means n/a (same as "----" in the selector) + memorySpaceId = memorySpaceId.trim(); + if (memorySpaceId.length() == 0) { + memorySpaceId = null; + } + else { + // Check that the ID requested by the user is a valid one + if (fGotoMemorySpaceControl.indexOf(memorySpaceId) == -1) { + throw new IllegalArgumentException("unrecognized memory space ID"); + } + } + + fGotoMemorySpaceControl.setText(memorySpaceId == null ? NA_MEMORY_SPACE_ID : memorySpaceId); + } + } + + fGotoAddressBar.setExpressionText(expression); + performGo(inNewTab, expression, memorySpaceId); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.ui.memory.memorybrowser.api.IMemoryBrowser#getSelectedMemorySpace() + */ + public String getSelectedMemorySpace() { + if (!fGotoMemorySpaceControl.isDisposed() && fGotoMemorySpaceControl.isVisible()) { + String id = fGotoMemorySpaceControl.getText(); + return id.equals(NA_MEMORY_SPACE_ID) ? null : id; + } + return null; + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/ColorAndEffectFieldEditor.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/ColorAndEffectFieldEditor.java index be63a48eeea..328e5fd926e 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/ColorAndEffectFieldEditor.java +++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/ColorAndEffectFieldEditor.java @@ -1,99 +1,99 @@ -/*******************************************************************************
- * Copyright (c) 2013 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 - Initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.debug.ui.memory.traditional;
-
-import org.eclipse.jface.preference.ColorSelector;
-import org.eclipse.jface.preference.FieldEditor;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.preference.PreferenceConverter;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-public class ColorAndEffectFieldEditor extends FieldEditor {
-
- private final String nameBold;
- private final String nameItalic;
- private final String nameBox;
-
- private ColorSelector colorSelector;
- private Button checkBold;
- private Button checkItalic;
- private Button checkBox; // :)
-
- public ColorAndEffectFieldEditor(String name, String nameBold, String nameItalic, String nameBox, String labelText, Composite parent) {
- super(name, labelText, parent);
- this.nameBold = nameBold;
- this.nameItalic = nameItalic;
- this.nameBox = nameBox;
- }
-
- @Override
- protected void adjustForNumColumns(int numColumns) {
- ((GridData) checkItalic.getLayoutData()).horizontalSpan = numColumns - 4;
- }
-
- @Override
- protected void doFillIntoGrid(Composite parent, int numColumns) {
- Control control = getLabelControl(parent);
- control.setLayoutData(new GridData());
-
- colorSelector = new ColorSelector(parent);
- colorSelector.getButton().setLayoutData(new GridData());
-
- checkBold = new Button(parent, SWT.CHECK);
- checkBold.setText(TraditionalRenderingMessages.getString("ColorAndEffectFieldEditor.bold"));
- checkBold.setLayoutData(new GridData());
-
- checkItalic = new Button(parent, SWT.CHECK);
- checkItalic.setText(TraditionalRenderingMessages.getString("ColorAndEffectFieldEditor.italic"));
- checkItalic.setLayoutData(new GridData());
-
- checkBox = new Button(parent, SWT.CHECK);
- checkBox.setText(TraditionalRenderingMessages.getString("ColorAndEffectFieldEditor.box"));
- checkBox.setLayoutData(new GridData());
- }
-
- @Override
- protected void doLoad() {
- IPreferenceStore store = getPreferenceStore();
- colorSelector.setColorValue(PreferenceConverter.getColor(store, getPreferenceName()));
- checkBold.setSelection(store.getBoolean(nameBold));
- checkItalic.setSelection(store.getBoolean(nameItalic));
- checkBox.setSelection(store.getBoolean(nameBox));
- }
-
- @Override
- protected void doLoadDefault() {
- IPreferenceStore store = getPreferenceStore();
- colorSelector.setColorValue(PreferenceConverter.getDefaultColor(store, getPreferenceName()));
- checkBold.setSelection(store.getDefaultBoolean(nameBold));
- checkItalic.setSelection(store.getDefaultBoolean(nameItalic));
- checkBox.setSelection(store.getDefaultBoolean(nameBox));
- }
-
- @Override
- protected void doStore() {
- IPreferenceStore store = getPreferenceStore();
- PreferenceConverter.setValue(store, getPreferenceName(), colorSelector.getColorValue());
- store.setValue(nameBold, checkBold.getSelection());
- store.setValue(nameItalic, checkItalic.getSelection());
- store.setValue(nameBox, checkBox.getSelection());
- }
-
- @Override
- public int getNumberOfControls() {
- return 5;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2013 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 - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.memory.traditional; + +import org.eclipse.jface.preference.ColorSelector; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +public class ColorAndEffectFieldEditor extends FieldEditor { + + private final String nameBold; + private final String nameItalic; + private final String nameBox; + + private ColorSelector colorSelector; + private Button checkBold; + private Button checkItalic; + private Button checkBox; // :) + + public ColorAndEffectFieldEditor(String name, String nameBold, String nameItalic, String nameBox, String labelText, Composite parent) { + super(name, labelText, parent); + this.nameBold = nameBold; + this.nameItalic = nameItalic; + this.nameBox = nameBox; + } + + @Override + protected void adjustForNumColumns(int numColumns) { + ((GridData) checkItalic.getLayoutData()).horizontalSpan = numColumns - 4; + } + + @Override + protected void doFillIntoGrid(Composite parent, int numColumns) { + Control control = getLabelControl(parent); + control.setLayoutData(new GridData()); + + colorSelector = new ColorSelector(parent); + colorSelector.getButton().setLayoutData(new GridData()); + + checkBold = new Button(parent, SWT.CHECK); + checkBold.setText(TraditionalRenderingMessages.getString("ColorAndEffectFieldEditor.bold")); + checkBold.setLayoutData(new GridData()); + + checkItalic = new Button(parent, SWT.CHECK); + checkItalic.setText(TraditionalRenderingMessages.getString("ColorAndEffectFieldEditor.italic")); + checkItalic.setLayoutData(new GridData()); + + checkBox = new Button(parent, SWT.CHECK); + checkBox.setText(TraditionalRenderingMessages.getString("ColorAndEffectFieldEditor.box")); + checkBox.setLayoutData(new GridData()); + } + + @Override + protected void doLoad() { + IPreferenceStore store = getPreferenceStore(); + colorSelector.setColorValue(PreferenceConverter.getColor(store, getPreferenceName())); + checkBold.setSelection(store.getBoolean(nameBold)); + checkItalic.setSelection(store.getBoolean(nameItalic)); + checkBox.setSelection(store.getBoolean(nameBox)); + } + + @Override + protected void doLoadDefault() { + IPreferenceStore store = getPreferenceStore(); + colorSelector.setColorValue(PreferenceConverter.getDefaultColor(store, getPreferenceName())); + checkBold.setSelection(store.getDefaultBoolean(nameBold)); + checkItalic.setSelection(store.getDefaultBoolean(nameItalic)); + checkBox.setSelection(store.getDefaultBoolean(nameBox)); + } + + @Override + protected void doStore() { + IPreferenceStore store = getPreferenceStore(); + PreferenceConverter.setValue(store, getPreferenceName(), colorSelector.getColorValue()); + store.setValue(nameBold, checkBold.getSelection()); + store.setValue(nameItalic, checkItalic.getSelection()); + store.setValue(nameBox, checkBox.getSelection()); + } + + @Override + public int getNumberOfControls() { + return 5; + } + +} |