diff options
Diffstat (limited to 'memory')
4 files changed, 192 insertions, 101 deletions
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/ClearExpressionsListAction.java b/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/ClearExpressionsListAction.java index 13c41a528a0..413c1391613 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/ClearExpressionsListAction.java +++ b/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/ClearExpressionsListAction.java @@ -27,7 +27,7 @@ public class ClearExpressionsListAction implements IViewActionDelegate { public void run(IAction action) { if ( fView instanceof MemoryBrowser ) { MemoryBrowser browser = (MemoryBrowser) fView; - browser.clearExpressionsFromList(null); + browser.clearExpressionHistoryForActiveTab(); } } diff --git a/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/GoToAddressBarWidget.java b/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/GoToAddressBarWidget.java index f860a3f4a8a..fdc8c5ccfe6 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/GoToAddressBarWidget.java +++ b/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/GoToAddressBarWidget.java @@ -14,10 +14,9 @@ package org.eclipse.cdt.debug.ui.memory.memorybrowser; import java.util.ArrayList; import java.util.Iterator; import java.util.Map; -import java.util.Set; import java.util.StringTokenizer; -import org.eclipse.cdt.debug.core.model.provisional.ITargetLabelProvider; +import org.eclipse.cdt.debug.core.model.provisional.IRecurringDebugContext; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; @@ -43,8 +42,19 @@ import org.eclipse.ui.PlatformUI; public class GoToAddressBarWidget { - private static String SEPARATOR = "<sperator>"; - private static String UNKNOWN_TARGET_NAME = "Unknown"; + /** + * Character sequence that is unlikely to appear naturally in a recurring + * debug context ID or memory space ID + */ + private static String SEPARATOR = "<seperator>"; + + /** + * At a minimum, the expression history is kept on a per launch + * configuration basis. Where debug contexts (processes, in practice) can + * provide a recurring ID, we further divide the history by those IDs. This + * constant is used when no recurring context ID is available. + */ + private static String UNKNOWN_CONTEXT_ID = "Unknown"; private Combo fExpression; private ControlDecoration fEmptyExpression; private ControlDecoration fWrongExpression; @@ -87,10 +97,12 @@ public class GoToAddressBarWidget { return fComposite; } + /** The launch configuration attribute prefix used to persist expression history */ private final static String SAVED_EXPRESSIONS = "saved_expressions"; //$NON-NLS-1$ + private final static int MAX_SAVED_EXPRESSIONS = 15 ; - private void saveExpression( String memorySpace, Object context, String expr ) { + private void addExpressionToHistoryPersistence( Object context, String expr, String memorySpace ) { /* * Get the saved expressions if any. * @@ -104,7 +116,7 @@ public class GoToAddressBarWidget { return; } - String targetName = getTargetName(context); + String contextID = getRecurringContextID(context); ILaunchConfiguration launchConfiguration = launch.getLaunchConfiguration(); String currentExpressions = ""; @@ -112,7 +124,7 @@ public class GoToAddressBarWidget { try { ILaunchConfigurationWorkingCopy wc = launchConfiguration.getWorkingCopy(); if (wc != null) { - currentExpressions = wc.getAttribute(getSaveExpressionKey(targetName,memorySpace), ""); + currentExpressions = wc.getAttribute(getSaveExpressionKey(contextID,memorySpace), ""); StringTokenizer st = new StringTokenizer(currentExpressions, ","); //$NON-NLS-1$ /* @@ -141,7 +153,7 @@ public class GoToAddressBarWidget { } currentExpressions += list.get(idx); } - wc.setAttribute(getSaveExpressionKey(targetName,memorySpace), currentExpressions); + wc.setAttribute(getSaveExpressionKey(contextID,memorySpace), currentExpressions); wc.doSave(); } } @@ -151,47 +163,67 @@ public class GoToAddressBarWidget { } } - public void deleteExpressions(Object context) { - - if(context == null) - { + /** + * Clear all expression history persisted in the launch configuration that + * created the given debug context + * + * @param context + * the debug context. In practice, this will always be a process + * context + */ + public void clearExpressionHistoryPersistence(Object context) { + if(context == null) { return; } ILaunch launch = getLaunch(context); - if(launch == null) - { + if(launch == null) { return; } + + // We maintain history for every process this launch configuration has + // launched. And where memory spaces are involved, each space has its + // own history. Here we just wipe out the persistence of all processes + // and memory spaces stored in the launch configuration that created the + // given processes. ILaunchConfiguration launchConfiguration = launch.getLaunchConfiguration(); if (launchConfiguration != null) { try { ILaunchConfigurationWorkingCopy wc = launchConfiguration.getWorkingCopy(); if (wc != null) { - @SuppressWarnings("unchecked") - Map<String,Object> attributes = (Map<String,Object>)wc.getAttributes(); - if (attributes != null && !attributes.isEmpty()) { - - Iterator<String> iterator = attributes.keySet().iterator(); - while(iterator.hasNext()) - { - String key = iterator.next(); - if(key.startsWith(SAVED_EXPRESSIONS)) - { - wc.removeAttribute(key); - } + Map<?,?> attributes = wc.getAttributes(); + Iterator<?> iterator = attributes.keySet().iterator(); + while (iterator.hasNext()) { + String key = (String)iterator.next(); + if (key.startsWith(SAVED_EXPRESSIONS)) { + wc.removeAttribute(key); } - wc.doSave(); - } + } + wc.doSave(); } } catch(CoreException e) { + // Some unexpected snag working with the launch configuration + MemoryBrowserPlugin.log(e); } } - } - private String[] getSavedExpressions(String memorySpace, Object context) { + /** + * Get the expression history persisted in the launch configuration for the + * given debug context and memory space (where applicable) + * + * @param context + * the debug context. In practice, this will always be a process + * context + * @param memorySpace + * memory space ID or null if not applicable + * @return a list of expressions, or empty collection if no history + * available (never null) + * @throws CoreException + * if there's a problem working with the launch configuration + */ + private String[] getSavedExpressions(Object context, String memorySpace) throws CoreException { /* * Get the saved expressions if any. * @@ -201,19 +233,14 @@ public class GoToAddressBarWidget { */ ILaunch launch = getLaunch(context); - if(launch == null) - { + if(launch == null) { return new String[0]; } ILaunchConfiguration launchConfiguration = launch.getLaunchConfiguration(); String expressions = ""; if (launchConfiguration != null) { - try { - expressions = launchConfiguration.getAttribute(getSaveExpressionKey(getTargetName(context),memorySpace), ""); - } - catch(CoreException e) { - } + expressions = launchConfiguration.getAttribute(getSaveExpressionKey(getRecurringContextID(context),memorySpace), ""); } StringTokenizer st = new StringTokenizer(expressions, ","); //$NON-NLS-1$ @@ -221,30 +248,43 @@ public class GoToAddressBarWidget { * Parse through the list creating an ordered array for display. */ ArrayList<String> list = new ArrayList<String>(); - while(st.hasMoreElements()) - { - String expr = (String) st.nextElement(); - list.add(expr); + while(st.hasMoreElements()) { + list.add(st.nextToken()); } return list.toArray(new String[list.size()]); } - public void loadSavedExpressions(String memorySpace, Object context) + /** + * Populate the expression history combobox based on the history persisted + * in the launch configuration for the given context and memory space (where + * applicable) + * + * @param context + * the debug context. In practice, this will always be a process + * context + * @param memorySpace + * memory space ID; null if not applicable + */ + public void loadSavedExpressions(Object context, String memorySpace) { - String[] expressions = getSavedExpressions(memorySpace, context); - String text = fExpression.getText(); - fExpression.removeAll(); - for(int idx=0; idx < expressions.length; idx++) - { - fExpression.add(expressions[idx]); - } - if(text != null) - { - fExpression.setText(text); + + try { + String[] expressions = getSavedExpressions(context, memorySpace); + String currentExpression = fExpression.getText(); + fExpression.removeAll(); + for (String expression : expressions) { + fExpression.add(expression); + } + if (currentExpression != null) { + fExpression.setText(currentExpression); + } + } catch (CoreException e) { + // Unexpected snag dealing with launch configuration + MemoryBrowserPlugin.log(e); } } - public void addExpressionToList( String memorySpace, Object context, String expr ) { + public void addExpressionToHistory(Object context, String expr, String memorySpace) { /* * Make sure it does not already exist, we do not want to show duplicates. */ @@ -257,7 +297,7 @@ public class GoToAddressBarWidget { } /* - * Add the new expression to the dropdown. + * Add the new expression to the combobox */ fExpression.add(expr); @@ -265,20 +305,28 @@ public class GoToAddressBarWidget { /* * Add it to the persistense database. */ - saveExpression(memorySpace, context, expr); + addExpressionToHistoryPersistence(context, expr, memorySpace); } - public void clearExpressionsFromList(String[] memorySpaces, Object context) { + /** + * Clears the history of expressions for the given debug context, both in + * the GUI and the persistence data + * + * @param context + * the debug context. In practice, this will always be a process + * context. + */ + public void clearExpressionHistory(Object context) { /* - * Clean up the combo list. + * Clear the combobox */ fExpression.removeAll(); fExpression.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); /* - * Clean out the expression persistense. + * Clear the history persisted in the launch configuration */ - deleteExpressions(context); + clearExpressionHistoryPersistence(context); /* * Make sure the status image indicator shows OK. @@ -407,38 +455,52 @@ public class GoToAddressBarWidget { } - private String getTargetName(Object context) + /** + * Get the identifier for the given context if it is a recurring one. See + * {@link IRecurringDebugContext} + * + * @param context + * the debug context + * @return the ID or UNKNOWN_CONTEXT_ID if the context is non-recurring or + * can't provide us its ID + */ + private String getRecurringContextID(Object context) { - String targetName = null; - if(context instanceof IAdaptable) - { + String id = UNKNOWN_CONTEXT_ID; + if (context instanceof IAdaptable) { IAdaptable adaptable = (IAdaptable) context; - ITargetLabelProvider labelProvider = (ITargetLabelProvider)adaptable.getAdapter(ITargetLabelProvider.class); - if(labelProvider != null) - { - try - { - targetName = labelProvider.getLabel(); + IRecurringDebugContext recurringDebugContext = (IRecurringDebugContext)adaptable.getAdapter(IRecurringDebugContext.class); + if (recurringDebugContext != null) { + try { + id = recurringDebugContext.getContextID(); } - catch(DebugException e) - { + catch(DebugException e) { + // If the context can't give us the ID, just treat it as a + // non-recurring context } } } - if(targetName == null || targetName.trim().length() == 0) - { - targetName = UNKNOWN_TARGET_NAME; - } - return targetName; + return id; } - private String getSaveExpressionKey(String targetName, String memorySpace) - { - String key = SAVED_EXPRESSIONS + SEPARATOR + targetName.trim(); - if(memorySpace != null && memorySpace.trim().length() > 0) - { - key += SEPARATOR + memorySpace.trim(); + /** + * Get a key that we can use to persist the expression history for the given + * debug context and memory space (where applicable). The key is used within + * the scope of a launch configuration. + * + * @param contextID + * a recurring debug context ID; see + * {@link IRecurringDebugContext} + * @param memorySpace + * a memory space identifier, or null if not applicable + * @return they key which will be used to persist the expression history + */ + private String getSaveExpressionKey(String contextID, String memorySpace) { + assert contextID.length() > 0; + String key = SAVED_EXPRESSIONS + SEPARATOR + contextID; + if (memorySpace != null && memorySpace.length() > 0) { + key += SEPARATOR + memorySpace; } return key; } 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 0c5e710bf48..bd4a356b839 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 @@ -23,7 +23,6 @@ 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.core.model.provisional.ITargetLabelProvider; import org.eclipse.cdt.debug.internal.core.CRequest; import org.eclipse.cdt.debug.ui.provisional.IRepositionableMemoryRendering2; import org.eclipse.core.runtime.CoreException; @@ -84,6 +83,7 @@ import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.custom.StackLayout; 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; @@ -241,36 +241,31 @@ public class MemoryBrowser extends ViewPart implements IDebugContextListener, IM fGotoAddressBar = new GoToAddressBarWidget(); fGotoAddressBarControl = fGotoAddressBar.createControl(fMainComposite); - fGotoAddressBar.getButton(IDialogConstants.OK_ID).addSelectionListener(new SelectionListener() { - public void widgetDefaultSelected(SelectionEvent e) {} + fGotoAddressBar.getButton(IDialogConstants.OK_ID).addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { performGo(false); } }); - fGotoAddressBar.getButton(GoToAddressBarWidget.ID_GO_NEW_TAB).addSelectionListener(new SelectionListener() { - public void widgetDefaultSelected(SelectionEvent e) {} + fGotoAddressBar.getButton(GoToAddressBarWidget.ID_GO_NEW_TAB).addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { performGo(true); } }); - fGotoAddressBar.getExpressionWidget().addSelectionListener(new SelectionListener() { - public void widgetSelected(SelectionEvent e) {} + fGotoAddressBar.getExpressionWidget().addSelectionListener(new SelectionAdapter() { public void widgetDefaultSelected(SelectionEvent e) { performGo(false); } }); - fGotoMemorySpaceControl.addSelectionListener(new SelectionListener() { - public void widgetDefaultSelected(SelectionEvent e) {} + fGotoMemorySpaceControl.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { - if(fGotoMemorySpaceControl.getItemCount() >= 2) - { + if(fGotoMemorySpaceControl.getItemCount() >= 2) { final CTabFolder activeFolder = (CTabFolder) fStackLayout.topControl; if (activeFolder != null) { final Object context = activeFolder.getData(KEY_CONTEXT); - fGotoAddressBar.loadSavedExpressions(fGotoMemorySpaceControl.getText(), context); + fGotoAddressBar.loadSavedExpressions(context, fGotoMemorySpaceControl.getText()); } } } @@ -336,11 +331,14 @@ public class MemoryBrowser extends ViewPart implements IDebugContextListener, IM return false; } - public void clearExpressionsFromList(String memorySpace) { + /** + * 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.clearExpressionsFromList(fGotoMemorySpaceControl.isVisible() ? fGotoMemorySpaceControl.getItems() : new String[]{""}, context); + fGotoAddressBar.clearExpressionHistory(context); } } @@ -422,7 +420,7 @@ public class MemoryBrowser extends ViewPart implements IDebugContextListener, IM if (activeFolder != null) { context = activeFolder.getData(KEY_CONTEXT); } - fGotoAddressBar.addExpressionToList(memorySpace, context, expression); + fGotoAddressBar.addExpressionToHistory(context, expression, memorySpace); performGo(inNewTab, expression, memorySpace); } } @@ -909,7 +907,7 @@ public class MemoryBrowser extends ViewPart implements IDebugContextListener, IM CTabItem tabItem = (CTabItem)e.item; updateExpression(tabItem); updateMemorySpaceControlSelection(tabItem); - fGotoAddressBar.loadSavedExpressions(fGotoMemorySpaceControl.isVisible() ? fGotoMemorySpaceControl.getText() : "", context); + fGotoAddressBar.loadSavedExpressions(context, fGotoMemorySpaceControl.isVisible() ? fGotoMemorySpaceControl.getText() : null); getSite().getSelectionProvider().setSelection(new StructuredSelection(tabItem.getData(KEY_RENDERING))); handleTabActivated(tabItem); } @@ -920,7 +918,7 @@ public class MemoryBrowser extends ViewPart implements IDebugContextListener, IM fStackLayout.topControl = tabFolder; // set empty initial expression fGotoAddressBar.setExpressionText(""); //$NON-NLS-1$ - fGotoAddressBar.loadSavedExpressions(fGotoMemorySpaceControl.isVisible() ? fGotoMemorySpaceControl.getText() : "", context); + fGotoAddressBar.loadSavedExpressions(context, fGotoMemorySpaceControl.isVisible() ? fGotoMemorySpaceControl.getText() : null); } // update debug context to the new selection tabFolder.setData(KEY_CONTEXT, context); @@ -955,7 +953,7 @@ public class MemoryBrowser extends ViewPart implements IDebugContextListener, IM updateExpression(activeFolder.getSelection()); updateMemorySpaceControlSelection(activeFolder.getSelection()); - fGotoAddressBar.loadSavedExpressions(fGotoMemorySpaceControl.isVisible() ? fGotoMemorySpaceControl.getText() : "", context); + fGotoAddressBar.loadSavedExpressions(context, fGotoMemorySpaceControl.isVisible() ? fGotoMemorySpaceControl.getText() : null); fStackLayout.topControl.getParent().layout(true); } diff --git a/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/MemoryBrowserPlugin.java b/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/MemoryBrowserPlugin.java index eac2bc52272..cfbd5e9a981 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/MemoryBrowserPlugin.java +++ b/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/MemoryBrowserPlugin.java @@ -11,6 +11,9 @@ package org.eclipse.cdt.debug.ui.memory.memorybrowser; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; @@ -69,4 +72,32 @@ public class MemoryBrowserPlugin extends AbstractUIPlugin { public static ImageDescriptor getImageDescriptor(String path) { return imageDescriptorFromPlugin(PLUGIN_ID, path); } + + /** + * Logs the specified status with this plug-in's log. + * + * @param status status to log + */ + public static void log(IStatus status) { + getDefault().getLog().log(status); + } + + /** + * Logs the specified throwable with this plug-in's log. + * + * @param t throwable to log + */ + public static void log(Throwable t) { + log(newErrorStatus("Error logged from Debug UI: ", t)); //$NON-NLS-1$ + } + + /** + * Returns a new error status for this plug-in with the given message + * @param message the message to be included in the status + * @param exception the exception to be included in the status or <code>null</code> if none + * @return a new error status + */ + public static IStatus newErrorStatus(String message, Throwable exception) { + return new Status(IStatus.ERROR, PLUGIN_ID, IDebugUIConstants.INTERNAL_ERROR, message, exception); + } } |