From 7c29ca49ce6006e677c8fae86500ab82827bb2ff Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 23 Mar 2012 11:39:34 -0700 Subject: [PATCH] Bug 374988 - [breakpoints] Update "Add Watchpoint" action and "Add Event Breakpoint" actions to use new dialog --- .../cdt/debug/core/ICWatchpointTarget.java | 58 +++ .../internal/core/ICWatchpointTarget.java | 53 +-- .../debug/internal/core/model/CVariable.java | 2 +- debug/org.eclipse.cdt.debug.ui/plugin.xml | 8 +- .../ui/actions/AddWatchpointDialog.java | 419 ++++++++++++++++- ...AddWatchpointOnVariableActionDelegate.java | 22 + .../breakpoints/AddWatchpointDialog.java | 439 ------------------ .../AddWatchpointOnMemoryActionDelegate.java | 129 ----- ...AddWatchpointOnVariableActionDelegate.java | 179 ------- .../breakpoints/ToggleBreakpointAdapter.java | 4 +- .../breakpoints/ToggleTracepointAdapter.java | 2 +- .../BreakpointsMessages.properties | 2 + .../CBreakpointPreferenceStore.java | 3 +- .../breakpoints/CBreakpointPropertyPage.java | 292 ++++++++++++ .../ui/preferences/ComboFieldEditor.java | 6 +- .../AbstractToggleBreakpointAdapter.java | 179 ++++++- .../AddWatchpointActionDelegate.java | 79 +--- ...AddWatchpointOnVariableActionDelegate.java | 93 ++++ .../ui/viewmodel/GdbVariableVMNode.java | 2 +- 19 files changed, 1093 insertions(+), 878 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICWatchpointTarget.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/AddWatchpointOnVariableActionDelegate.java delete mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointDialog.java delete mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointOnMemoryActionDelegate.java delete mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointOnVariableActionDelegate.java rename debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/{internal/ui/actions => ui}/breakpoints/AddWatchpointActionDelegate.java (53%) create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AddWatchpointOnVariableActionDelegate.java diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICWatchpointTarget.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICWatchpointTarget.java new file mode 100644 index 00000000000..3ade51c8a72 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICWatchpointTarget.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2010 Freescale Semiconductor 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: + * Freescale Semiconductor - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.core; + +import org.eclipse.debug.core.IRequest; + +/** + * View model types for which the "Add Watchpoint (C/C++)" action is applicable + * should implement this interface. The action is a popupMenu/objectContribution + * that targets this type. + * + * @since 7.2 + */ +public interface ICWatchpointTarget { + + /** IRequest object used in the asynchronous method {@link ICWatchpointTarget#getSize()} */ + interface GetSizeRequest extends IRequest { + int getSize(); // returns -1 if size not available + void setSize(int size); + }; + + interface CanCreateWatchpointRequest extends IRequest { + boolean getCanCreate(); + void setCanCreate(boolean value); + }; + + /** + * Determine if a watchpoint can be set on the element. The result does not + * guarantee an attempt to set such a watchpoint will succeed. This is + * merely a way to find out whether it makes sense to even attempt it. For + * example, an expression that's not an l-value should return false. The + * implementation may choose to go even further and check that the target + * supports watchpoints (at all or at that particular location). + */ + void canSetWatchpoint(CanCreateWatchpointRequest request); + + /** + * Get the expression or the name of the variable + */ + String getExpression(); + + /** + * Asynchronous method to retrieve the size of the variable/expression, in + * bytes. + * + * @param request + * the async request object + */ + void getSize(GetSizeRequest request); +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/ICWatchpointTarget.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/ICWatchpointTarget.java index 61d9a2a0ba8..d8a3888309d 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/ICWatchpointTarget.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/ICWatchpointTarget.java @@ -1,60 +1,19 @@ /******************************************************************************* - * Copyright (c) 2010 Freescale Semiconductor and others. + * Copyright (c) 2012 Wind River Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: - * Freescale Semiconductor - initial API and implementation + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.debug.internal.core; -import org.eclipse.debug.core.IRequest; - /** - * View model types for which the "Add Watchpoint (C/C++)" action is applicable - * should implement this interface. The action is a popupMenu/objectContribution - * that targets this type. - * - *

- * Note that the action is particular to CBreakpoint, and not all CDT debugger - * solutions use CBreakpoint. + * @deprecated This interface has been moved to a public package. Use + * {@link org.eclipse.cdt.debug.core.ICWatchpointTarget} instead. */ -public interface ICWatchpointTarget { +public interface ICWatchpointTarget extends org.eclipse.cdt.debug.core.ICWatchpointTarget { - /** IRequest object used in the asynchronous method {@link ICWatchpointTarget#getSize()} */ - interface GetSizeRequest extends IRequest { - int getSize(); // returns -1 if size not available - void setSize(int size); - }; - - interface CanCreateWatchpointRequest extends IRequest { - boolean getCanCreate(); - void setCanCreate(boolean value); - }; - - /** - * Determine if a watchpoint can be set on the element. The result does not - * guarantee an attempt to set such a watchpoint will succeed. This is - * merely a way to find out whether it makes sense to even attempt it. For - * example, an expression that's not an l-value should return false. The - * implementation may choose to go even further and check that the target - * supports watchpoints (at all or at that particular location). - */ - void canSetWatchpoint(CanCreateWatchpointRequest request); - - /** - * Get the expression or the name of the variable - */ - String getExpression(); - - /** - * Asynchronous method to retrieve the size of the variable/expression, in - * bytes. - * - * @param request - * the async request object - */ - void getSize(GetSizeRequest request); } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CVariable.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CVariable.java index 87537c2c313..76f17b4de21 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CVariable.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CVariable.java @@ -15,6 +15,7 @@ import com.ibm.icu.text.MessageFormat; import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.core.ICDebugConstants; +import org.eclipse.cdt.debug.core.ICWatchpointTarget; import org.eclipse.cdt.debug.core.cdi.event.ICDIChangedEvent; import org.eclipse.cdt.debug.core.cdi.event.ICDIDestroyedEvent; import org.eclipse.cdt.debug.core.cdi.event.ICDIEvent; @@ -33,7 +34,6 @@ import org.eclipse.cdt.debug.core.model.ICDebugElementStatus; import org.eclipse.cdt.debug.core.model.ICType; import org.eclipse.cdt.debug.core.model.ICValue; import org.eclipse.cdt.debug.internal.core.CSettingsManager; -import org.eclipse.cdt.debug.internal.core.ICWatchpointTarget; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index afdcbfac5a5..76eee9c0b5e 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -636,7 +636,7 @@ objectClass="org.eclipse.cdt.debug.internal.core.ICWatchpointTarget" id="org.eclipse.cdt.debug.ui.WatchpointActions"> sExpressionHistory = new ArrayList(); + + private boolean fHasMemorySpaceControls; + private Button fMemorySpaceEnableButton; + private Combo fMemorySpaceInput; + private String fMemorySpace; + + private boolean fRangeInitialEnable; + private Button fRangeEnableButton; + private Text fRangeField; + private String fRange = ""; //$NON-NLS-1$ + + private Button fChkBtnWrite; + private Button fChkBtnRead; + private boolean fRead; + private boolean fWrite; + + private ICDIMemorySpaceManagement fMemManagement; + + + /** + * Constructor for AddWatchpointDialog. + * + * @param parentShell + */ public AddWatchpointDialog( Shell parentShell, ICDIMemorySpaceManagement memMgmt ) { - super(parentShell, memMgmt); + super( parentShell ); + setShellStyle( getShellStyle() | SWT.RESIZE ); + fMemManagement = memMgmt; } + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Control createDialogArea( Composite parent ) { + // The button bar will work better if we make the parent composite + // a single column grid layout. For the widgets we add, we want a + // a two-column grid, so we just create a sub composite for that. + GridLayout gridLayout = new GridLayout(); + parent.setLayout( gridLayout ); + GridData gridData = new GridData( GridData.FILL_BOTH ); + parent.setLayoutData( gridData ); + Composite composite = new Composite( parent, SWT.None ); + gridLayout = new GridLayout(); + gridLayout.numColumns = 2; + composite.setLayout( gridLayout ); + parent = composite; + + // Create the controls + createExpressionControl( parent ); + boolean hasDebugContext = DebugUITools.getDebugContext() != null; + boolean hasMemorySpaces = hasDebugContext && fMemManagement != null && fMemManagement.getMemorySpaces() != null && fMemManagement.getMemorySpaces().length > 0; + fHasMemorySpaceControls = !hasDebugContext || hasMemorySpaces; + if ( fHasMemorySpaceControls ) { + createMemorySpaceControl( parent, hasMemorySpaces ); + } + createCountField( parent ); + createAccessWidgets( parent ); + + // Initialize the inter-control state + if ( fExpression != null && fExpression.length() > 0 ) { + fExpressionInput.add( fExpression, 0 ); + fExpressionInput.select( 0 ); + } + fExpressionInput.setFocus(); + if ( fHasMemorySpaceControls ) { + fMemorySpaceInput.setEnabled( fMemorySpaceEnableButton.getEnabled() ); + } + fRangeField.setEnabled( fRangeEnableButton.getEnabled() ); + updateUI(); + return parent; + } + + private void createExpressionControl(Composite parent ) { + + Label l = new Label( parent, GridData.FILL_HORIZONTAL ); + l.setText( ActionMessages.getString( "AddWatchpointDialog.1" ) ); //$NON-NLS-1$ + GridData gridData = new GridData( GridData.FILL_HORIZONTAL ); + gridData.horizontalSpan = 2; + l.setLayoutData( gridData ); + + fExpressionInput = new Combo( parent, SWT.BORDER ); + gridData = new GridData( GridData.FILL_HORIZONTAL ); + gridData.horizontalSpan = 2; + fExpressionInput.setLayoutData( gridData ); + fExpressionInput.addModifyListener( this ); + for (String expression : sExpressionHistory) { + fExpressionInput.add( expression ); + } + } + + private void createMemorySpaceControl( Composite parent, boolean hasMemorySpaces ) { + fMemorySpaceEnableButton = new Button( parent, SWT.CHECK ); + GridData gridData = new GridData( GridData.FILL_HORIZONTAL ); + gridData.horizontalSpan = 1; + fMemorySpaceEnableButton.setLayoutData( gridData ); + fMemorySpaceEnableButton.setText( ActionMessages.getString( "AddWatchpointDialog.5" ) ); //$NON-NLS-1$ + fMemorySpaceEnableButton.setSelection( false ); + fMemorySpaceEnableButton.addSelectionListener( this ); + + if ( hasMemorySpaces ) { + fMemorySpaceInput = new Combo( parent, SWT.BORDER | SWT.READ_ONLY ); + } else { + fMemorySpaceInput = new Combo( parent, SWT.BORDER ); + } + gridData = new GridData( GridData.FILL_HORIZONTAL ); + gridData.horizontalSpan = 1; + fMemorySpaceInput.setLayoutData( gridData ); + fMemorySpaceInput.addSelectionListener( this ); + if ( fMemManagement != null ) { + String [] memorySpaces = fMemManagement.getMemorySpaces(); + for ( int i = 0; i < memorySpaces.length; i++ ) { + fMemorySpaceInput.add( memorySpaces[i] ); + } + } + if ( fMemorySpace != null && fMemorySpace.length() > 0 ) { + int i = fMemorySpaceInput.indexOf( fMemorySpace ); + if ( i >= 0 ) { + fMemorySpaceInput.select( i ); + fMemorySpaceEnableButton.setSelection( true ); + } else { + fMemorySpaceInput.add( fMemorySpace ); + } + } + fMemorySpaceInput.addModifyListener( this ); + //234909 - for accessibility + fMemorySpaceInput.getAccessible().addAccessibleListener( + new AccessibleAdapter() { + @Override + public void getName(AccessibleEvent e) { + e.result = ActionMessages.getString( "AddWatchpointDialog.5" ); //$NON-NLS-1$ + } + + }); + } + + /** + * @param text + * @param c + * @return true if the concatenation of text + c results + * in a valid string representation of an integer + * @see verifyIntegerText() + */ + private static boolean verifyIntegerTextAddition( String text, char c ) { + + // pass through all control characters + if ( Character.isISOControl( c ) ) { + return true; + } + + // case-insensitive + c = Character.toLowerCase( c ); + text = text.toLowerCase(); + + // first character has to be 0-9 + if ( text.length() == 0 ) { + return Character.isDigit( c ); + } + + // second character must be x if preceded by a 0, otherwise 0-9 will do + if ( text.length() == 1 ) { + if ( text.equals( "0" ) ) { //$NON-NLS-1$ + return c == 'x'; + } + return Character.isDigit( c ); + } + + // all subsequent characters must be 0-9 or a-f if started with 0x + return Character.isDigit( c ) + || text.startsWith( "0x" ) && 'a' <= c && c <= 'f'; //$NON-NLS-1$ + } + + /** + * @param text integer string built up using verifyIntegerTextAddition() + * @return true if text represents a valid string representation of + * an integer + */ + private static boolean verifyIntegerText( String text ) { + if ( text.length() == 0 ) { + return false; + } + if ( text.length() == 1 ) { + return true; + } + if ( text.length() == 2 ) { + return !text.equals("0x"); //$NON-NLS-1$ + } + return true; + } + + private void createCountField( Composite parent ) { + fRangeEnableButton = new Button( parent, SWT.CHECK ); + GridData gridData = new GridData( GridData.FILL_HORIZONTAL ); + gridData.horizontalSpan = 1; + fRangeEnableButton.setLayoutData( gridData ); + fRangeEnableButton.setText( ActionMessages.getString( "AddWatchpointDialog.6" ) ); //$NON-NLS-1$ + fRangeEnableButton.setSelection( fRangeInitialEnable && fRange.length() > 0 ); + fRangeEnableButton.addSelectionListener( this ); + + fRangeField = new Text( parent, SWT.BORDER ); + gridData = new GridData( GridData.FILL_HORIZONTAL ); + gridData.horizontalSpan = 1; + GC gc = new GC( fRangeField ); + FontMetrics fm = gc.getFontMetrics(); + gridData.minimumWidth = 8 * fm.getAverageCharWidth(); + fRangeField.setLayoutData( gridData ); + fRangeField.setText( fRange ); + fRangeField.addVerifyListener( new VerifyListener() { + @Override + public void verifyText( VerifyEvent e ) { + e.doit = verifyIntegerTextAddition( fRangeField.getText(), e.character ); + } + }); + fRangeField.addModifyListener( this ); + //234909 - for accessibility + fRangeField.getAccessible().addAccessibleListener( + new AccessibleAdapter() { + @Override + public void getName(AccessibleEvent e) { + e.result = ActionMessages.getString( "AddWatchpointDialog.6" ); //$NON-NLS-1$ + } + + }); + } + + private void createAccessWidgets( Composite parent ) { + GridData gridData = new GridData( GridData.FILL_HORIZONTAL ); + gridData.horizontalSpan = 3; + + Group group = new Group( parent, SWT.NONE ); + group.setLayout( new GridLayout() ); + group.setLayoutData( gridData ); + group.setText( ActionMessages.getString( "AddWatchpointDialog.2" ) ); //$NON-NLS-1$ + fChkBtnWrite = new Button( group, SWT.CHECK ); + fChkBtnWrite.setText( ActionMessages.getString( "AddWatchpointDialog.3" ) ); //$NON-NLS-1$ + fChkBtnWrite.setSelection( true ); + fChkBtnWrite.addSelectionListener( this ); + fChkBtnRead = new Button( group, SWT.CHECK ); + fChkBtnRead.setText( ActionMessages.getString( "AddWatchpointDialog.4" ) ); //$NON-NLS-1$ + fChkBtnRead.setSelection( false ); + fChkBtnRead.addSelectionListener( this ); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) + */ + @Override + protected void configureShell( Shell newShell ) { + super.configureShell( newShell ); + + // use the same title used by the platform dialog + newShell.setText( ActionMessages.getString( "AddWatchpointDialog.0" ) ); //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#okPressed() + */ + @Override + protected void okPressed() { + fExpression = fExpressionInput.getText().trim(); + if ( fExpression.length() > 0 ) { + addHistory( fExpression ); + } + if ( fHasMemorySpaceControls ) { + fMemorySpace = fMemorySpaceEnableButton.getSelection() ? fMemorySpaceInput.getText().trim() : ""; //$NON-NLS-1$ + } + fRange = fRangeEnableButton.getSelection() ? fRangeField.getText().trim() : "0"; //$NON-NLS-1$ + fRead = fChkBtnRead.getSelection(); + fWrite = fChkBtnWrite.getSelection(); + super.okPressed(); + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent) + */ + @Override + public void modifyText( ModifyEvent e ) { + updateUI(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.TrayDialog#createButtonBar(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Control createButtonBar( Composite parent ) { + return super.createButtonBar( parent ); + } + + public String getExpression() { + return fExpression; + } + + public String getMemorySpace() { + return fMemorySpace; + } + + private static void addHistory( String item ) { + if ( !sExpressionHistory.contains( item ) ) { + sExpressionHistory.add( 0, item ); + + if ( sExpressionHistory.size() > 5 ) + sExpressionHistory.remove( sExpressionHistory.size() - 1 ); + } + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetDefaultSelected( SelectionEvent e ) { + // ignore + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected( SelectionEvent e ) { + updateUI(); + } + + private void updateUI() { + if ( fHasMemorySpaceControls ) { + fMemorySpaceInput.setEnabled( fMemorySpaceEnableButton.getSelection() ); + } + fRangeField.setEnabled( fRangeEnableButton.getSelection() ); + Button b = getButton( IDialogConstants.OK_ID ); + if ( b == null ) { + return; + } + b.setEnabled( okayEnabled() ); + } + + private boolean okayEnabled() { + if ( !fChkBtnRead.getSelection() && !fChkBtnWrite.getSelection() ) { + return false ; + } + if ( fExpressionInput.getText().length() == 0 ) { + return false; + } + if ( fHasMemorySpaceControls && fMemorySpaceInput.getEnabled() && fMemorySpaceInput.getText().length() == 0 ) { + return false; + } + if ( fRangeField.getEnabled() + && ( fRangeField.getText().length() == 0 || !verifyIntegerText( fRangeField.getText() ) ) ) { + return false; + } + return true; + } + + public boolean getWriteAccess() { + return fWrite; + } + + public boolean getReadAccess() { + return fRead; + } + + public void setExpression(String expressionString ) { + fExpression = expressionString; + } + + public BigInteger getRange() { + return BigInteger.valueOf( Long.decode(fRange).longValue() ); + } + + public void initializeRange( boolean enable, String range ) { + fRangeInitialEnable = enable; + fRange = range; + } + + public void initializeMemorySpace( String memorySpace ) { + fMemorySpace = memorySpace; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + // override so we can change the initial okay enabled state + createButton( parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, + true ).setEnabled( okayEnabled() ); + createButton( parent, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false ); + } + } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/AddWatchpointOnVariableActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/AddWatchpointOnVariableActionDelegate.java new file mode 100644 index 00000000000..8cfe88f155a --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/AddWatchpointOnVariableActionDelegate.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2012 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.actions; + +/** + * This class was moved to a public package and this implementation is left here + * for backward compatibility for clients that used this internal class. + * + * @deprecated Use the {@link org.eclipse.cdt.debug.ui.breakpoints.AddWatchpointOnVariableActionDelegate} + * class instead. + */ +public class AddWatchpointOnVariableActionDelegate extends org.eclipse.cdt.debug.ui.breakpoints.AddWatchpointOnVariableActionDelegate{ + +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointDialog.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointDialog.java deleted file mode 100644 index 8144e4d4cd4..00000000000 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointDialog.java +++ /dev/null @@ -1,439 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004, 2008, 2008 QNX Software Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * QNX Software Systems - Initial API and implementation - * Freescale Semiconductor - Address watchpoints, https://bugs.eclipse.org/bugs/show_bug.cgi?id=118299 - * IBM Corporation - *******************************************************************************/ -package org.eclipse.cdt.debug.internal.ui.actions.breakpoints; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.cdt.debug.core.cdi.model.ICDIMemorySpaceManagement; -import org.eclipse.cdt.debug.internal.ui.actions.ActionMessages; -import org.eclipse.debug.ui.DebugUITools; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.accessibility.AccessibleAdapter; -import org.eclipse.swt.accessibility.AccessibleEvent; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.VerifyEvent; -import org.eclipse.swt.events.VerifyListener; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * The "Add Watchpoint" dialog of the "Toggle watchpoint" action. - * @deprecated Replaced by opening a properties dialog on a new breakpoint. - */ -public class AddWatchpointDialog extends Dialog implements ModifyListener, SelectionListener { - - private Combo fExpressionInput; - private String fExpression; - private static List sExpressionHistory = new ArrayList(); - - private boolean fHasMemorySpaceControls; - private Button fMemorySpaceEnableButton; - private Combo fMemorySpaceInput; - private String fMemorySpace; - - private boolean fRangeInitialEnable; - private Button fRangeEnableButton; - private Text fRangeField; - private String fRange = ""; //$NON-NLS-1$ - - private Button fChkBtnWrite; - private Button fChkBtnRead; - private boolean fRead; - private boolean fWrite; - - private ICDIMemorySpaceManagement fMemManagement; - - - /** - * Constructor for AddWatchpointDialog. - * - * @param parentShell - */ - public AddWatchpointDialog( Shell parentShell, ICDIMemorySpaceManagement memMgmt ) { - super( parentShell ); - setShellStyle( getShellStyle() | SWT.RESIZE ); - fMemManagement = memMgmt; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) - */ - @Override - protected Control createDialogArea( Composite parent ) { - // The button bar will work better if we make the parent composite - // a single column grid layout. For the widgets we add, we want a - // a two-column grid, so we just create a sub composite for that. - GridLayout gridLayout = new GridLayout(); - parent.setLayout( gridLayout ); - GridData gridData = new GridData( GridData.FILL_BOTH ); - parent.setLayoutData( gridData ); - Composite composite = new Composite( parent, SWT.None ); - gridLayout = new GridLayout(); - gridLayout.numColumns = 2; - composite.setLayout( gridLayout ); - parent = composite; - - // Create the controls - createExpressionControl( parent ); - boolean hasDebugContext = DebugUITools.getDebugContext() != null; - boolean hasMemorySpaces = hasDebugContext && fMemManagement != null && fMemManagement.getMemorySpaces() != null && fMemManagement.getMemorySpaces().length > 0; - fHasMemorySpaceControls = !hasDebugContext || hasMemorySpaces; - if ( fHasMemorySpaceControls ) { - createMemorySpaceControl( parent, hasMemorySpaces ); - } - createCountField( parent ); - createAccessWidgets( parent ); - - // Initialize the inter-control state - if ( fExpression != null && fExpression.length() > 0 ) { - fExpressionInput.add( fExpression, 0 ); - fExpressionInput.select( 0 ); - } - fExpressionInput.setFocus(); - if ( fHasMemorySpaceControls ) { - fMemorySpaceInput.setEnabled( fMemorySpaceEnableButton.getEnabled() ); - } - fRangeField.setEnabled( fRangeEnableButton.getEnabled() ); - updateUI(); - return parent; - } - - private void createExpressionControl(Composite parent ) { - - Label l = new Label( parent, GridData.FILL_HORIZONTAL ); - l.setText( ActionMessages.getString( "AddWatchpointDialog.1" ) ); //$NON-NLS-1$ - GridData gridData = new GridData( GridData.FILL_HORIZONTAL ); - gridData.horizontalSpan = 2; - l.setLayoutData( gridData ); - - fExpressionInput = new Combo( parent, SWT.BORDER ); - gridData = new GridData( GridData.FILL_HORIZONTAL ); - gridData.horizontalSpan = 2; - fExpressionInput.setLayoutData( gridData ); - fExpressionInput.addModifyListener( this ); - for (String expression : sExpressionHistory) { - fExpressionInput.add( expression ); - } - } - - private void createMemorySpaceControl( Composite parent, boolean hasMemorySpaces ) { - fMemorySpaceEnableButton = new Button( parent, SWT.CHECK ); - GridData gridData = new GridData( GridData.FILL_HORIZONTAL ); - gridData.horizontalSpan = 1; - fMemorySpaceEnableButton.setLayoutData( gridData ); - fMemorySpaceEnableButton.setText( ActionMessages.getString( "AddWatchpointDialog.5" ) ); //$NON-NLS-1$ - fMemorySpaceEnableButton.setSelection( false ); - fMemorySpaceEnableButton.addSelectionListener( this ); - - if ( hasMemorySpaces ) { - fMemorySpaceInput = new Combo( parent, SWT.BORDER | SWT.READ_ONLY ); - } else { - fMemorySpaceInput = new Combo( parent, SWT.BORDER ); - } - gridData = new GridData( GridData.FILL_HORIZONTAL ); - gridData.horizontalSpan = 1; - fMemorySpaceInput.setLayoutData( gridData ); - fMemorySpaceInput.addSelectionListener( this ); - if ( fMemManagement != null ) { - String [] memorySpaces = fMemManagement.getMemorySpaces(); - for ( int i = 0; i < memorySpaces.length; i++ ) { - fMemorySpaceInput.add( memorySpaces[i] ); - } - } - if ( fMemorySpace != null && fMemorySpace.length() > 0 ) { - int i = fMemorySpaceInput.indexOf( fMemorySpace ); - if ( i >= 0 ) { - fMemorySpaceInput.select( i ); - fMemorySpaceEnableButton.setSelection( true ); - } else { - fMemorySpaceInput.add( fMemorySpace ); - } - } - fMemorySpaceInput.addModifyListener( this ); - //234909 - for accessibility - fMemorySpaceInput.getAccessible().addAccessibleListener( - new AccessibleAdapter() { - @Override - public void getName(AccessibleEvent e) { - e.result = ActionMessages.getString( "AddWatchpointDialog.5" ); //$NON-NLS-1$ - } - - }); - } - - /** - * @param text - * @param c - * @return true if the concatenation of text + c results - * in a valid string representation of an integer - * @see verifyIntegerText() - */ - private static boolean verifyIntegerTextAddition( String text, char c ) { - - // pass through all control characters - if ( Character.isISOControl( c ) ) { - return true; - } - - // case-insensitive - c = Character.toLowerCase( c ); - text = text.toLowerCase(); - - // first character has to be 0-9 - if ( text.length() == 0 ) { - return Character.isDigit( c ); - } - - // second character must be x if preceded by a 0, otherwise 0-9 will do - if ( text.length() == 1 ) { - if ( text.equals( "0" ) ) { //$NON-NLS-1$ - return c == 'x'; - } - return Character.isDigit( c ); - } - - // all subsequent characters must be 0-9 or a-f if started with 0x - return Character.isDigit( c ) - || text.startsWith( "0x" ) && 'a' <= c && c <= 'f'; //$NON-NLS-1$ - } - - /** - * @param text integer string built up using verifyIntegerTextAddition() - * @return true if text represents a valid string representation of - * an integer - */ - private static boolean verifyIntegerText( String text ) { - if ( text.length() == 0 ) { - return false; - } - if ( text.length() == 1 ) { - return true; - } - if ( text.length() == 2 ) { - return !text.equals("0x"); //$NON-NLS-1$ - } - return true; - } - - private void createCountField( Composite parent ) { - fRangeEnableButton = new Button( parent, SWT.CHECK ); - GridData gridData = new GridData( GridData.FILL_HORIZONTAL ); - gridData.horizontalSpan = 1; - fRangeEnableButton.setLayoutData( gridData ); - fRangeEnableButton.setText( ActionMessages.getString( "AddWatchpointDialog.6" ) ); //$NON-NLS-1$ - fRangeEnableButton.setSelection( fRangeInitialEnable && fRange.length() > 0 ); - fRangeEnableButton.addSelectionListener( this ); - - fRangeField = new Text( parent, SWT.BORDER ); - gridData = new GridData( GridData.FILL_HORIZONTAL ); - gridData.horizontalSpan = 1; - GC gc = new GC( fRangeField ); - FontMetrics fm = gc.getFontMetrics(); - gridData.minimumWidth = 8 * fm.getAverageCharWidth(); - fRangeField.setLayoutData( gridData ); - fRangeField.setText( fRange ); - fRangeField.addVerifyListener( new VerifyListener() { - @Override - public void verifyText( VerifyEvent e ) { - e.doit = verifyIntegerTextAddition( fRangeField.getText(), e.character ); - } - }); - fRangeField.addModifyListener( this ); - //234909 - for accessibility - fRangeField.getAccessible().addAccessibleListener( - new AccessibleAdapter() { - @Override - public void getName(AccessibleEvent e) { - e.result = ActionMessages.getString( "AddWatchpointDialog.6" ); //$NON-NLS-1$ - } - - }); - } - - private void createAccessWidgets( Composite parent ) { - GridData gridData = new GridData( GridData.FILL_HORIZONTAL ); - gridData.horizontalSpan = 3; - - Group group = new Group( parent, SWT.NONE ); - group.setLayout( new GridLayout() ); - group.setLayoutData( gridData ); - group.setText( ActionMessages.getString( "AddWatchpointDialog.2" ) ); //$NON-NLS-1$ - fChkBtnWrite = new Button( group, SWT.CHECK ); - fChkBtnWrite.setText( ActionMessages.getString( "AddWatchpointDialog.3" ) ); //$NON-NLS-1$ - fChkBtnWrite.setSelection( true ); - fChkBtnWrite.addSelectionListener( this ); - fChkBtnRead = new Button( group, SWT.CHECK ); - fChkBtnRead.setText( ActionMessages.getString( "AddWatchpointDialog.4" ) ); //$NON-NLS-1$ - fChkBtnRead.setSelection( false ); - fChkBtnRead.addSelectionListener( this ); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) - */ - @Override - protected void configureShell( Shell newShell ) { - super.configureShell( newShell ); - - // use the same title used by the platform dialog - newShell.setText( ActionMessages.getString( "AddWatchpointDialog.0" ) ); //$NON-NLS-1$ - } - - /* (non-Javadoc) - * @see org.eclipse.jface.dialogs.Dialog#okPressed() - */ - @Override - protected void okPressed() { - fExpression = fExpressionInput.getText().trim(); - if ( fExpression.length() > 0 ) { - addHistory( fExpression ); - } - if ( fHasMemorySpaceControls ) { - fMemorySpace = fMemorySpaceEnableButton.getSelection() ? fMemorySpaceInput.getText().trim() : ""; //$NON-NLS-1$ - } - fRange = fRangeEnableButton.getSelection() ? fRangeField.getText().trim() : "0"; //$NON-NLS-1$ - fRead = fChkBtnRead.getSelection(); - fWrite = fChkBtnWrite.getSelection(); - super.okPressed(); - } - - /* (non-Javadoc) - * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent) - */ - @Override - public void modifyText( ModifyEvent e ) { - updateUI(); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.dialogs.TrayDialog#createButtonBar(org.eclipse.swt.widgets.Composite) - */ - @Override - protected Control createButtonBar( Composite parent ) { - return super.createButtonBar( parent ); - } - - public String getExpression() { - return fExpression; - } - - public String getMemorySpace() { - return fMemorySpace; - } - - private static void addHistory( String item ) { - if ( !sExpressionHistory.contains( item ) ) { - sExpressionHistory.add( 0, item ); - - if ( sExpressionHistory.size() > 5 ) - sExpressionHistory.remove( sExpressionHistory.size() - 1 ); - } - } - - /* (non-Javadoc) - * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) - */ - @Override - public void widgetDefaultSelected( SelectionEvent e ) { - // ignore - } - - /* (non-Javadoc) - * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) - */ - @Override - public void widgetSelected( SelectionEvent e ) { - updateUI(); - } - - private void updateUI() { - if ( fHasMemorySpaceControls ) { - fMemorySpaceInput.setEnabled( fMemorySpaceEnableButton.getSelection() ); - } - fRangeField.setEnabled( fRangeEnableButton.getSelection() ); - Button b = getButton( IDialogConstants.OK_ID ); - if ( b == null ) { - return; - } - b.setEnabled( okayEnabled() ); - } - - private boolean okayEnabled() { - if ( !fChkBtnRead.getSelection() && !fChkBtnWrite.getSelection() ) { - return false ; - } - if ( fExpressionInput.getText().length() == 0 ) { - return false; - } - if ( fHasMemorySpaceControls && fMemorySpaceInput.getEnabled() && fMemorySpaceInput.getText().length() == 0 ) { - return false; - } - if ( fRangeField.getEnabled() - && ( fRangeField.getText().length() == 0 || !verifyIntegerText( fRangeField.getText() ) ) ) { - return false; - } - return true; - } - - public boolean getWriteAccess() { - return fWrite; - } - - public boolean getReadAccess() { - return fRead; - } - - public void setExpression(String expressionString ) { - fExpression = expressionString; - } - - public BigInteger getRange() { - return BigInteger.valueOf( Long.decode(fRange).longValue() ); - } - - public void initializeRange( boolean enable, String range ) { - fRangeInitialEnable = enable; - fRange = range; - } - - public void initializeMemorySpace( String memorySpace ) { - fMemorySpace = memorySpace; - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - // override so we can change the initial okay enabled state - createButton( parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, - true ).setEnabled( okayEnabled() ); - createButton( parent, IDialogConstants.CANCEL_ID, - IDialogConstants.CANCEL_LABEL, false ); - } - -} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointOnMemoryActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointOnMemoryActionDelegate.java deleted file mode 100644 index 01e61b53471..00000000000 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointOnMemoryActionDelegate.java +++ /dev/null @@ -1,129 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Nokia 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: - * Nokia - initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.debug.internal.ui.actions.breakpoints; - - -import java.math.BigInteger; - -import org.eclipse.cdt.debug.internal.core.model.CMemoryBlockExtension; -import org.eclipse.cdt.debug.ui.CDebugUIPlugin; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.debug.core.DebugException; -import org.eclipse.debug.core.model.IMemoryBlock; -import org.eclipse.debug.core.model.IMemoryBlockExtension; -import org.eclipse.debug.core.model.MemoryByte; -import org.eclipse.debug.ui.memory.IRepositionableMemoryRendering; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.window.Window; -import org.eclipse.ui.IActionDelegate; -import org.eclipse.ui.IObjectActionDelegate; -import org.eclipse.ui.IWorkbenchPart; - - -public class AddWatchpointOnMemoryActionDelegate extends AddWatchpointActionDelegate { - - /** - * Constructor for Action1. - */ - public AddWatchpointOnMemoryActionDelegate() { - super(); - } - - /** - * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) - */ - public void setActivePart(IAction action, IWorkbenchPart targetPart) {} - - /** - * @see IActionDelegate#run(IAction) - */ - @Override - public void run(IAction action) { - IStructuredSelection selection = getSelection(); - - if (selection == null || selection.isEmpty()) { - return; - } - - Object obj = selection.getFirstElement(); - if (obj != null) { - String memorySpace = null; - String address = ""; //$NON-NLS-1$ - String range = "1"; //$NON-NLS-1$ - - if (obj instanceof IAdaptable) { - IRepositionableMemoryRendering rendering = (IRepositionableMemoryRendering) ((IAdaptable)obj).getAdapter(IRepositionableMemoryRendering.class); - if (rendering != null) { - int addressableSize = 1; - IMemoryBlock memblock = rendering.getMemoryBlock(); - if (memblock instanceof IMemoryBlockExtension) { - try { - addressableSize = ((IMemoryBlockExtension)memblock).getAddressableSize(); - } catch (DebugException e) { - CDebugUIPlugin.log(e); - } - } - - memorySpace = getMemorySpace(rendering.getMemoryBlock(), memorySpace); - address = getSelectedAddress(rendering.getSelectedAddress(), address); - range = getRange(rendering.getSelectedAsBytes(), addressableSize, range); - } - } - - AddWatchpointDialog dlg = new AddWatchpointDialog(CDebugUIPlugin.getActiveWorkbenchShell(), - getMemorySpaceManagement()); - dlg.initializeMemorySpace(memorySpace); - dlg.setExpression(address); - dlg.initializeRange(true, range); - - if (dlg.open() == Window.OK) { - addWatchpoint(dlg.getWriteAccess(), dlg.getReadAccess(), dlg.getExpression(), dlg.getMemorySpace(), dlg.getRange()); - } - } - } - - private String getMemorySpace(IMemoryBlock memBlock, String def) { - if (memBlock != null && memBlock instanceof CMemoryBlockExtension) { - return ((CMemoryBlockExtension)memBlock).getMemorySpaceID(); - } - return def; - } - - private String getSelectedAddress(BigInteger selectedAddress, String def) { - if (selectedAddress != null) { - return "0x" + selectedAddress.toString(16); //$NON-NLS-1$ - } - return def; - } - - private String getRange(MemoryByte[] selectedBytes, int addressableSize, String def) { - if (selectedBytes != null && selectedBytes.length > 0) { - return Integer.toString(selectedBytes.length / addressableSize); - } - return def; - } - - /** - * @see IActionDelegate#selectionChanged(IAction, ISelection) - */ - - /* (non-Javadoc) - * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection) - */ - @Override - public void selectionChanged(IAction action, ISelection selection) {} - - private IStructuredSelection getSelection() { - return (IStructuredSelection)getView().getViewSite().getSelectionProvider().getSelection(); - } -} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointOnVariableActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointOnVariableActionDelegate.java deleted file mode 100644 index 66a5d5e03de..00000000000 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointOnVariableActionDelegate.java +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Nokia 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: - * Nokia - initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.debug.internal.ui.actions.breakpoints; - - -import org.eclipse.cdt.debug.internal.core.CRequest; -import org.eclipse.cdt.debug.internal.core.ICWatchpointTarget; -import org.eclipse.cdt.debug.internal.ui.actions.ActionMessages; -import org.eclipse.cdt.debug.ui.CDebugUIPlugin; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.jface.window.Window; -import org.eclipse.ui.IObjectActionDelegate; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.progress.WorkbenchJob; - -/** - * Invoked when user right clicks on an element in the Variables or Expressions - * view and selects 'Add Watchpoint (C/C++)' - */ -public class AddWatchpointOnVariableActionDelegate extends AddWatchpointActionDelegate implements IObjectActionDelegate { - - /** The target variable/expression */ - private ICWatchpointTarget fVar; - - /** The view where fVar was selected */ - private IWorkbenchPart fActivePart; - - /** - * Constructor - */ - public AddWatchpointOnVariableActionDelegate() { - super(); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart) - */ - @Override - public void setActivePart(IAction action, IWorkbenchPart targetPart) { - fActivePart = targetPart; - } - - private static class GetSizeRequest extends CRequest implements ICWatchpointTarget.GetSizeRequest { - int fSize = -1; - @Override - public int getSize() { - return fSize; - } - @Override - public void setSize(int size) { - fSize = size; - } - }; - - /* (non-Javadoc) - * @see org.eclipse.cdt.debug.internal.ui.actions.AddWatchpointActionDelegate#run(org.eclipse.jface.action.IAction) - */ - @Override - public void run(IAction action) { - if (fVar == null) { - return; - } - - final String expr = fVar.getExpression(); - if (expr == null) { - assert false : "how are we getting an empty expression?"; //$NON-NLS-1$ - return; - } - - // Getting the size of the variable/expression is an asynchronous - // operation...or at least the API is (the CDI implementation reacts - // synchronously) - final ICWatchpointTarget.GetSizeRequest request = new GetSizeRequest() { - @Override - public void done() { - if (isSuccess()) { - // Now that we have the size, put up a dialog to create the watchpoint - final int size = getSize(); - assert size > 0 : "unexpected variale/expression size"; //$NON-NLS-1$ - WorkbenchJob job = new WorkbenchJob("open watchpoint dialog") { //$NON-NLS-1$ - @Override - public IStatus runInUIThread(IProgressMonitor monitor) { - AddWatchpointDialog dlg = new AddWatchpointDialog(CDebugUIPlugin.getActiveWorkbenchShell(), - getMemorySpaceManagement()); - dlg.setExpression(expr); - dlg.initializeRange(false, Integer.toString(size)); - if (dlg.open() == Window.OK) { - addWatchpoint(dlg.getWriteAccess(), dlg.getReadAccess(), dlg.getExpression(), dlg.getMemorySpace(), dlg.getRange()); - } - return Status.OK_STATUS; - } - }; - job.setSystem(true); - job.schedule(); - } - else { - WorkbenchJob job = new WorkbenchJob("watchpoint error") { //$NON-NLS-1$ - @Override - public IStatus runInUIThread(IProgressMonitor monitor) { - if (fActivePart != null) { - ErrorDialog.openError( fActivePart.getSite().getWorkbenchWindow().getShell(), ActionMessages.getString( "AddWatchpointOnVariableActionDelegate.Error_Dlg_Title" ), ActionMessages.getString( "AddWatchpointOnVariableActionDelegate.No_Element_Size" ), getStatus() ); //$NON-NLS-1$ //$NON-NLS-2$ - } - return Status.OK_STATUS; - } - }; - job.setSystem(true); - job.schedule(); - } - } - }; - fVar.getSize(request); - } - - private class CanCreateWatchpointRequest extends CRequest implements ICWatchpointTarget.CanCreateWatchpointRequest { - boolean fCanCreate; - @Override - public boolean getCanCreate() { - return fCanCreate; - } - @Override - public void setCanCreate(boolean value) { - fCanCreate = value; - } - }; - - /** - * Record the target variable/expression - * - * @see org.eclipse.ui.actions.ActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, - * org.eclipse.jface.viewers.ISelection) - */ - @Override - public void selectionChanged(final IAction action, ISelection selection) { - fVar = null; - if (selection == null || selection.isEmpty()) { - action.setEnabled(false); - return; - } - if (selection instanceof TreeSelection) { - Object obj = ((TreeSelection)selection).getFirstElement(); - fVar = (ICWatchpointTarget)DebugPlugin.getAdapter(obj, ICWatchpointTarget.class); - if (fVar != null) { - final ICWatchpointTarget.CanCreateWatchpointRequest request = new CanCreateWatchpointRequest() { - @Override - public void done() { - action.setEnabled(getCanCreate()); - } - }; - fVar.canSetWatchpoint(request); - return; - } - assert false : "action should not have been available for object " + obj; //$NON-NLS-1$ - } - else if (selection instanceof StructuredSelection) { - // Not sure why, but sometimes we get an extraneous empty StructuredSelection. Seems harmless enough - assert ((StructuredSelection)selection).getFirstElement() == null : "action installed in unexpected type of view/part"; //$NON-NLS-1$ - } - else { - assert false : "action installed in unexpected type of view/part"; //$NON-NLS-1$ - } - action.setEnabled(false); - } -} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleBreakpointAdapter.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleBreakpointAdapter.java index 41201f51497..c35d3537077 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleBreakpointAdapter.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleBreakpointAdapter.java @@ -89,12 +89,12 @@ public class ToggleBreakpointAdapter extends AbstractToggleBreakpointAdapter { @Override protected void createWatchpoint( boolean interactive, IWorkbenchPart part, String sourceHandle, IResource resource, - int charStart, int charEnd, int lineNumber, String expression) throws CoreException + int charStart, int charEnd, int lineNumber, String expression, String memorySpace, String range) throws CoreException { ICWatchpoint bp = CDIDebugModel.createBlankWatchpoint(); Map attributes = new HashMap(); CDIDebugModel.setWatchPointAttributes(attributes, sourceHandle, resource, true, false, - expression, "", new BigInteger("0"), true, 0, ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + expression, memorySpace, new BigInteger(range), true, 0, ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ openBreakpointPropertiesDialog(bp, part, resource, attributes); } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleTracepointAdapter.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleTracepointAdapter.java index 375c8f7f00f..0510d80ecdb 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleTracepointAdapter.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleTracepointAdapter.java @@ -81,7 +81,7 @@ public class ToggleTracepointAdapter extends AbstractToggleBreakpointAdapter { } protected void createWatchpoint( boolean interactive, IWorkbenchPart part, String sourceHandle, IResource resource, - int charStart, int charEnd, int lineNumber, String expression) throws CoreException + int charStart, int charEnd, int lineNumber, String expression, String memorySpace, String range) throws CoreException { } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/BreakpointsMessages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/BreakpointsMessages.properties index ecc61aa6bf0..45819b032fd 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/BreakpointsMessages.properties +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/BreakpointsMessages.properties @@ -31,6 +31,8 @@ CBreakpointPropertyPage.watchpointType_read_label=Read CBreakpointPropertyPage.watchpointType_write_label=Write CBreakpointPropertyPage.watchpoint_expression_label=Expression to watch: CBreakpointPropertyPage.watchpoint_expression_errorMessage=Enter the expression to watch: +CBreakpointPropertyPage.watchpoint_range_label=Range: +CBreakpointPropertyPage.watchpoint_memorySpace_label=Memory Space: CBreakpointPropertyPage.condition_label=&Condition: CBreakpointPropertyPage.condition_invalidValue_message=Invalid condition. CBreakpointPropertyPage.ignoreCount_label=&Ignore count: diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPreferenceStore.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPreferenceStore.java index c558db83b63..6a284f5039e 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPreferenceStore.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPreferenceStore.java @@ -52,7 +52,6 @@ public class CBreakpointPreferenceStore implements IPersistentPreferenceStore { private ListenerList fListeners; private final CBreakpointContext fContext; - // TODO: remove after fixing add event breapoint dialog. public CBreakpointPreferenceStore() { this (null, null); } @@ -220,7 +219,7 @@ public class CBreakpointPreferenceStore implements IPersistentPreferenceStore { } public String getString(String name) { - String retVal = null; + String retVal = ""; //$NON-NLS-1$ Object o = fProperties.get(name); if (o instanceof String) { retVal = (String)o; diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPropertyPage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPropertyPage.java index 587abcbfa04..68b8a6beb22 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPropertyPage.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPropertyPage.java @@ -13,11 +13,16 @@ package org.eclipse.cdt.debug.internal.ui.breakpoints; import org.eclipse.cdt.debug.core.CDIDebugModel; +import org.eclipse.cdt.debug.core.cdi.model.ICDIMemorySpaceManagement; +import org.eclipse.cdt.debug.core.cdi.model.ICDITarget; import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICDebugTarget; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; import org.eclipse.cdt.debug.core.model.ICWatchpoint; +import org.eclipse.cdt.debug.core.model.ICWatchpoint2; +import org.eclipse.cdt.debug.internal.ui.preferences.ComboFieldEditor; import org.eclipse.cdt.debug.ui.CDebugUIPlugin; import org.eclipse.cdt.debug.ui.breakpoints.CBreakpointUIContributionFactory; import org.eclipse.cdt.debug.ui.breakpoints.ICBreakpointContext; @@ -28,14 +33,25 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.ILineBreakpoint; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.contexts.IDebugContextProvider; import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.FieldEditor; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.IntegerFieldEditor; import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbenchPropertyPage; import org.eclipse.ui.model.IWorkbenchAdapter; @@ -164,6 +180,227 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement } } + class WatchpointRangeFieldEditor extends IntegerFieldEditor { + + private static final String DISABLED_VALUE = "0"; //$NON-NLS-1$ + private Button fCheckbox; + private boolean fWasSelected; + + public WatchpointRangeFieldEditor( String name, String labelText, Composite parent ) { + super( name, labelText, parent ); + } + + @Override + protected void doFillIntoGrid(Composite parent, int numColumns) { + getCheckboxControl(parent); + super.doFillIntoGrid(parent, numColumns); + } + + private Button getCheckboxControl(Composite parent) { + if (fCheckbox == null) { + Composite inner= new Composite(parent, SWT.NULL); + final GridLayout layout= new GridLayout(2, false); + layout.marginWidth = 0; + inner.setLayout(layout); + fCheckbox= new Button(inner, SWT.CHECK); + fCheckbox.setFont(parent.getFont()); + fCheckbox.setText(getLabelText()); + // create and hide label from base class + Label label = getLabelControl(inner); + label.setText(""); //$NON-NLS-1$ + label.setVisible(false); + fCheckbox.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + boolean isSelected = fCheckbox.getSelection(); + valueChanged(fWasSelected, isSelected); + fWasSelected = isSelected; + } + }); + } else { + checkParent(fCheckbox.getParent(), parent); + } + return fCheckbox; + } + + @Override + protected boolean checkState() { + if (fCheckbox != null && !fCheckbox.getSelection()) { + clearErrorMessage(); + return true; + } + return super.checkState(); + } + + @Override + public Label getLabelControl(Composite parent) { + final Label label= getLabelControl(); + if (label == null) { + return super.getLabelControl(parent); + } else { + checkParent(label.getParent(), parent); + } + return label; + } + + @Override + protected void doLoad() { + if (getTextControl() != null && fCheckbox != null && getLabelControl() != null) { + oldValue = getPreferenceStore().getString(getPreferenceName()); + boolean enabled = !DISABLED_VALUE.equals(oldValue); + getTextControl().setText(enabled ? oldValue : ""); //$NON-NLS-1$ + fCheckbox.setSelection(enabled); + fWasSelected = enabled; + getTextControl().setEnabled(enabled); + getLabelControl().setEnabled(enabled); + } + } + + @Override + protected void doStore() { + if (fCheckbox != null && !fCheckbox.getSelection()) { + getPreferenceStore().setValue(getPreferenceName(), DISABLED_VALUE); + } else { + Text text = getTextControl(); + if (text != null) { + getPreferenceStore().setValue(getPreferenceName(), text.getText().trim()); + } + } + } + + @Override + public int getIntValue() throws NumberFormatException { + if (fCheckbox != null && !fCheckbox.getSelection()) { + return 0; + } else { + return super.getIntValue(); + } + } + + protected void valueChanged(boolean oldValue, boolean newValue) { + if (oldValue != newValue) { + valueChanged(); + fireStateChanged(VALUE, oldValue, newValue); + getTextControl().setEnabled(newValue); + getLabelControl().setEnabled(newValue); + } + } + + } + + class WatchpointMemorySpaceFieldEditor extends ComboFieldEditor { + + private static final String DISABLED_VALUE = ""; //$NON-NLS-1$ + private Button fCheckbox; + private boolean fWasSelected; + + public WatchpointMemorySpaceFieldEditor( String name, String labelText, String[] memorySpaces, Composite parent ) { + super( name, labelText, makeArray2D(memorySpaces), parent ); + } + + @Override + protected void doFillIntoGrid(Composite parent, int numColumns) { + getCheckboxControl(parent); + super.doFillIntoGrid(parent, numColumns); + } + + private Button getCheckboxControl(Composite parent) { + if (fCheckbox == null) { + Composite inner= new Composite(parent, SWT.NULL); + final GridLayout layout= new GridLayout(2, false); + layout.marginWidth = 0; + inner.setLayout(layout); + fCheckbox= new Button(inner, SWT.CHECK); + fCheckbox.setFont(parent.getFont()); + fCheckbox.setText(getLabelText()); + // create and hide label from base class + Label label = getLabelControl(inner); + label.setText(""); //$NON-NLS-1$ + label.setVisible(false); + fCheckbox.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + boolean isSelected = fCheckbox.getSelection(); + valueChanged(fWasSelected, isSelected); + fWasSelected = isSelected; + } + }); + } else { + checkParent(fCheckbox.getParent(), parent); + } + return fCheckbox; + } + + @Override + public Label getLabelControl(Composite parent) { + final Label label= getLabelControl(); + if (label == null) { + return super.getLabelControl(parent); + } else { + checkParent(label.getParent(), parent); + } + return label; + } + + @Override + protected void doLoad() { + super.doLoad(); + if (fCheckbox != null && getLabelControl() != null) { + String value = getPreferenceStore().getString(getPreferenceName()); + boolean enabled = !DISABLED_VALUE.equals(value); + fCheckbox.setSelection(enabled); + fWasSelected = enabled; + getComboBoxControl().setEnabled(enabled); + getLabelControl().setEnabled(enabled); + } + } + + @Override + protected void doStore() { + if (fCheckbox != null && !fCheckbox.getSelection()) { + getPreferenceStore().setValue(getPreferenceName(), DISABLED_VALUE); + } else { + super.doStore(); + } + } + + protected void valueChanged(boolean oldValue, boolean newValue) { + if (oldValue != newValue) { + fireStateChanged(VALUE, oldValue, newValue); + getComboBoxControl().setEnabled(newValue); + getLabelControl().setEnabled(newValue); + } + } + + } + + private String[][] makeArray2D(String[] array) { + String[][] array2d = new String[array.length][]; + for (int i = 0; i < array.length; i++) { + array2d[i] = new String[2]; + array2d[i][0] = array2d[i][1] = array[i]; + } + return array2d; + } + + private ICDIMemorySpaceManagement getMemorySpaceManagement(){ + Object debugViewElement = getDebugContext(); + ICDIMemorySpaceManagement memMgr = null; + + if ( debugViewElement != null ) { + ICDebugTarget debugTarget = (ICDebugTarget)DebugPlugin.getAdapter(debugViewElement, ICDebugTarget.class); + + if ( debugTarget != null ){ + ICDITarget target = (ICDITarget)debugTarget.getAdapter(ICDITarget.class); + + if (target instanceof ICDIMemorySpaceManagement) + memMgr = (ICDIMemorySpaceManagement)target; + } + } + + return memMgr; + } + class LabelFieldEditor extends ReadOnlyFieldEditor { private String fValue; @@ -272,6 +509,8 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement addField( createLabelEditor( getFieldEditorParent(), BreakpointsMessages.getString( "CBreakpointPropertyPage.sourceHandle_label" ), filename ) ); //$NON-NLS-1$ } createWatchExpressionEditor(getFieldEditorParent()); + createWatchMemorySpaceEditor(getFieldEditorParent()); + createWatchRangeEditor(getFieldEditorParent()); createWatchTypeEditors(getFieldEditorParent()); } @@ -355,6 +594,46 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement } } + protected void createWatchMemorySpaceEditor( Composite parent ) { + ICBreakpoint breakpoint = getBreakpoint(); + if (breakpoint == null || breakpoint.getMarker() == null) { + ICDIMemorySpaceManagement memSpaceMgmt = getMemorySpaceManagement(); + if (memSpaceMgmt != null) { + String[] memorySpaces = memSpaceMgmt.getMemorySpaces(); + if (memorySpaces != null && memorySpaces.length != 0) { + addField( new WatchpointMemorySpaceFieldEditor( + ICWatchpoint2.MEMORYSPACE, + BreakpointsMessages.getString("CBreakpointPropertyPage.watchpoint_memorySpace_label"), //$NON-NLS-1$ + memorySpaces, + parent) ); + } + } + } else { + String memorySpace = getPreferenceStore().getString(ICWatchpoint2.MEMORYSPACE); + if (memorySpace != null && memorySpace.length() != 0) { + addField(createLabelEditor( + parent, + BreakpointsMessages.getString("CBreakpointPropertyPage.watchpoint_memorySpace_label"), //$NON-NLS-1$ + getPreferenceStore().getString(ICWatchpoint2.MEMORYSPACE) )); + } + } + } + + protected void createWatchRangeEditor( Composite parent ) { + ICBreakpoint breakpoint = getBreakpoint(); + if (breakpoint == null || breakpoint.getMarker() == null) { + addField( new WatchpointRangeFieldEditor( + ICWatchpoint2.RANGE, + BreakpointsMessages.getString("CBreakpointPropertyPage.watchpoint_range_label"), //$NON-NLS-1$ + parent) ); + } else { + addField(createLabelEditor( + parent, + BreakpointsMessages.getString("CBreakpointPropertyPage.watchpoint_range_label"), //$NON-NLS-1$ + getPreferenceStore().getString(ICWatchpoint2.RANGE) )); + } + } + protected void createWatchTypeEditors( Composite parent ) { // Edit read/write options only when creating the breakpoint. ICBreakpoint breakpoint = getBreakpoint(); @@ -404,6 +683,19 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement return (ICBreakpoint)element.getAdapter(ICBreakpoint.class); } } + + protected Object getDebugContext() { + IDebugContextProvider provider = (IDebugContextProvider)getElement().getAdapter(IDebugContextProvider.class); + if (provider != null) { + ISelection selection = provider.getActiveContext(); + if (selection instanceof IStructuredSelection) { + return ((IStructuredSelection) selection).getFirstElement(); + } + return null; + } + return DebugUITools.getDebugContext(); + } + protected IResource getResource() { IAdaptable element = getElement(); diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/preferences/ComboFieldEditor.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/preferences/ComboFieldEditor.java index bf197c2186c..40bceb60178 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/preferences/ComboFieldEditor.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/preferences/ComboFieldEditor.java @@ -139,7 +139,7 @@ public class ComboFieldEditor extends FieldEditor { /** * Lazily create and return the Combo control. */ - public Combo getComboBoxControl(Composite parent) { + protected Combo getComboBoxControl(Composite parent) { if (fCombo == null) { fCombo = new Combo(parent, SWT.READ_ONLY); for (int i = 0; i < fEntryNamesAndValues.length; i++) { @@ -160,6 +160,10 @@ public class ComboFieldEditor extends FieldEditor { return fCombo; } + protected Combo getComboBoxControl() { + return fCombo; + } + /** * Given the name (label) of an entry, return the corresponding value. */ diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AbstractToggleBreakpointAdapter.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AbstractToggleBreakpointAdapter.java index 22dd8d73e79..5e5d2f3edfa 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AbstractToggleBreakpointAdapter.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AbstractToggleBreakpointAdapter.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.debug.ui.breakpoints; +import java.math.BigInteger; import java.util.Iterator; import java.util.Map; @@ -24,10 +25,13 @@ import org.eclipse.cdt.core.model.IMethod; import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.IVariable; +import org.eclipse.cdt.debug.core.ICWatchpointTarget; import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; import org.eclipse.cdt.debug.core.model.ICWatchpoint; +import org.eclipse.cdt.debug.internal.core.CRequest; +import org.eclipse.cdt.debug.internal.core.model.CMemoryBlockExtension; import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils; import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; import org.eclipse.cdt.debug.internal.ui.actions.ActionMessages; @@ -43,13 +47,20 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IMemoryBlockExtension; +import org.eclipse.debug.core.model.MemoryByte; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension2; +import org.eclipse.debug.ui.memory.IRepositionableMemoryRendering; import org.eclipse.jface.preference.PreferenceDialog; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; @@ -68,6 +79,7 @@ import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.dialogs.PreferencesUtil; import org.eclipse.ui.editors.text.ILocationProvider; +import org.eclipse.ui.progress.WorkbenchJob; import org.eclipse.ui.texteditor.IEditorStatusLine; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.ui.texteditor.SimpleMarkerAnnotation; @@ -131,11 +143,19 @@ abstract public class AbstractToggleBreakpointAdapter if ( variable != null ) { updateVariableWatchpoint(true, false, part, variable); } + IRepositionableMemoryRendering rendering = getMemoryRendering(part, selection); + if (rendering != null) { + updateMemoryWatchpoint(true, false, part, rendering); + } + + } @Override public boolean canToggleWatchpoints( IWorkbenchPart part, ISelection selection ) { - return getVariableFromSelection( part, selection ) != null; + return getVariableFromSelection( part, selection ) != null || + getMemoryRendering(part, selection) != null || + getWatchpointTarget(part, selection) != null; } @Override @@ -171,13 +191,26 @@ abstract public class AbstractToggleBreakpointAdapter ICElement element = getCElementFromSelection( part, selection ); if (element instanceof IVariable) { updateVariableWatchpoint(false, true, part, (IVariable)element); - } else { - String text = ""; //$NON-NLS-1$ - if (selection instanceof ITextSelection) { - text = ((ITextSelection)selection).getText(); - } - createWatchpoint(true, part, null, ResourcesPlugin.getWorkspace().getRoot(), -1, -1, -1, text); + return; + } + + IRepositionableMemoryRendering rendering = getMemoryRendering(part, selection); + if (rendering != null) { + updateMemoryWatchpoint(false, true, part, rendering); + return; + } + + ICWatchpointTarget watchpointTarget = getWatchpointTarget(part, selection); + if (watchpointTarget != null) { + updateTargetWatchpoint(false, true, part, watchpointTarget); + return; } + + String text = ""; //$NON-NLS-1$ + if (selection instanceof ITextSelection) { + text = ((ITextSelection)selection).getText(); + } + createWatchpoint(true, part, null, ResourcesPlugin.getWorkspace().getRoot(), -1, -1, -1, text, null, "0"); //$NON-NLS-1$ } @Override @@ -366,10 +399,107 @@ abstract public class AbstractToggleBreakpointAdapter } catch (CModelException e) { CDebugUIPlugin.log(e); } - createWatchpoint(interactive, part, sourceHandle, resource, charStart, charEnd, lineNumber, expression); + createWatchpoint(interactive, part, sourceHandle, resource, charStart, charEnd, lineNumber, expression, null, "0"); //$NON-NLS-1$ } } + private void updateMemoryWatchpoint(boolean toggle, boolean interactive, IWorkbenchPart part, + IRepositionableMemoryRendering rendering) throws CoreException + { + int addressableSize = 1; + IMemoryBlock memblock = rendering.getMemoryBlock(); + if (memblock instanceof IMemoryBlockExtension) { + try { + addressableSize = ((IMemoryBlockExtension)memblock).getAddressableSize(); + } catch (DebugException e) { + CDebugUIPlugin.log(e); + } + } + + String memorySpace = getMemorySpace(rendering.getMemoryBlock(), null); + String address = getSelectedAddress(rendering.getSelectedAddress(), ""); //$NON-NLS-1$ + String range = getRange(rendering.getSelectedAsBytes(), addressableSize, "1"); //$NON-NLS-1$ + + createWatchpoint(interactive, part, "", ResourcesPlugin.getWorkspace().getRoot(), -1, -1, -1, address, //$NON-NLS-1$ + memorySpace, range); + } + + private String getMemorySpace(IMemoryBlock memBlock, String def) { + if (memBlock != null && memBlock instanceof CMemoryBlockExtension) { + return ((CMemoryBlockExtension)memBlock).getMemorySpaceID(); + } + return def; + } + + private String getSelectedAddress(BigInteger selectedAddress, String def) { + if (selectedAddress != null) { + return "0x" + selectedAddress.toString(16); //$NON-NLS-1$ + } + return def; + } + + private String getRange(MemoryByte[] selectedBytes, int addressableSize, String def) { + if (selectedBytes != null && selectedBytes.length > 0) { + return Integer.toString(selectedBytes.length / addressableSize); + } + return def; + } + + private void updateTargetWatchpoint(boolean toggle, final boolean interactive, final IWorkbenchPart part, + ICWatchpointTarget watchpointTarget) throws CoreException + { + String _expr = watchpointTarget.getExpression(); + if (_expr == null) { + _expr = ""; //$NON-NLS-1$ + } + final String expr = _expr; + + // Getting the size of the variable/expression is an asynchronous + // operation...or at least the API is (the CDI implementation reacts + // synchronously) + + class GetSizeRequest extends CRequest implements ICWatchpointTarget.GetSizeRequest { + int fSize = -1; + @Override + public int getSize() { + return fSize; + } + @Override + public void setSize(int size) { + fSize = size; + } + + @Override + public void done() { + int _size = 0; + if (isSuccess()) { + // Now that we have the size, put up a dialog to create the watchpoint + _size = getSize(); + assert _size > 0 : "unexpected variale/expression size"; //$NON-NLS-1$ + } + final int size = _size; + + WorkbenchJob job = new WorkbenchJob("open watchpoint dialog") { //$NON-NLS-1$ + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + try { + createWatchpoint(interactive, part, "", ResourcesPlugin.getWorkspace().getRoot(), //$NON-NLS-1$ + -1, -1, -1, expr, null, Integer.toString(size)); + } catch (CoreException e) { + return e.getStatus(); + } + return Status.OK_STATUS; + } + }; + job.setSystem(true); + job.schedule(); + } + }; + + watchpointTarget.getSize(new GetSizeRequest()); + + } + /** * Returns the C model element at the given selection. * @param part Workbench part where the selection is. @@ -440,7 +570,37 @@ abstract public class AbstractToggleBreakpointAdapter } return null; } + + protected IRepositionableMemoryRendering getMemoryRendering( IWorkbenchPart part, ISelection selection ) { + if (selection != null && selection instanceof IStructuredSelection && !selection.isEmpty()) { + Object obj = ((IStructuredSelection)selection).getFirstElement(); + if (obj != null) { + if (obj instanceof IAdaptable) { + return (IRepositionableMemoryRendering) ((IAdaptable)obj).getAdapter(IRepositionableMemoryRendering.class); + } + } + } + return null; + } + protected ICWatchpointTarget getWatchpointTarget( IWorkbenchPart part, ISelection selection ) { + if (selection != null && selection instanceof IStructuredSelection && !selection.isEmpty()) { + Object obj = ((IStructuredSelection)selection).getFirstElement(); + if (obj != null) { + if (obj instanceof IAdaptable) { + ICWatchpointTarget target = (ICWatchpointTarget) ((IAdaptable)obj).getAdapter(ICWatchpointTarget.class); + if (target == null) { + target = (ICWatchpointTarget) ((IAdaptable)obj).getAdapter( + org.eclipse.cdt.debug.internal.core.ICWatchpointTarget.class); + } + return target; + } + } + } + return null; + } + + /** * Reports the given error message to the user. * @param message Message to report. @@ -747,6 +907,7 @@ abstract public class AbstractToggleBreakpointAdapter * @throws CoreException Exception while creating breakpoint. */ protected abstract void createWatchpoint(boolean interactive, IWorkbenchPart part, String sourceHandle, - IResource resource, int charStart, int charEnd, int lineNumber, String expression) throws CoreException; + IResource resource, int charStart, int charEnd, int lineNumber, String expression, String memorySpace, + String range) throws CoreException; } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AddWatchpointActionDelegate.java similarity index 53% rename from debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointActionDelegate.java rename to debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AddWatchpointActionDelegate.java index 9fab7944647..d7993ef10a5 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/AddWatchpointActionDelegate.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AddWatchpointActionDelegate.java @@ -1,4 +1,4 @@ -/******************************************************************************* +/*******************************************************************************sb * Copyright (c) 2004, 2007-7 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -9,35 +9,32 @@ * QNX Software Systems - Initial API and implementation * Freescale Semiconductor - Address watchpoints, https://bugs.eclipse.org/bugs/show_bug.cgi?id=118299 *******************************************************************************/ -package org.eclipse.cdt.debug.internal.ui.actions.breakpoints; +package org.eclipse.cdt.debug.ui.breakpoints; -import java.math.BigInteger; - -import org.eclipse.cdt.debug.core.CDIDebugModel; -import org.eclipse.cdt.debug.core.cdi.model.ICDIMemorySpaceManagement; -import org.eclipse.cdt.debug.core.cdi.model.ICDITarget; -import org.eclipse.cdt.debug.core.model.ICDebugTarget; import org.eclipse.cdt.debug.internal.ui.actions.ActionMessages; +import org.eclipse.cdt.debug.internal.ui.actions.breakpoints.ToggleBreakpointAdapter; import org.eclipse.cdt.debug.ui.CDebugUIPlugin; -import org.eclipse.cdt.debug.ui.breakpoints.IToggleBreakpointsTargetCExtension; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IObjectActionDelegate; import org.eclipse.ui.IViewActionDelegate; import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.actions.ActionDelegate; /** - * A delegate for the "Add Watchpoint" action. + * A delegate for the "Add Watchpoint" action. Clients can register this object on + * a model-specific element which supports a toggle breakpoints target. + * + * @noextend This class is not intended to be subclassed by clients. + * @since 7.2 */ -public class AddWatchpointActionDelegate extends ActionDelegate implements IViewActionDelegate { +public class AddWatchpointActionDelegate extends ActionDelegate implements IViewActionDelegate, IObjectActionDelegate { - private IViewPart fView; + private IWorkbenchPart fPart; private ISelection fSelection; private ToggleBreakpointAdapter fDefaultToggleTarget = new ToggleBreakpointAdapter(); @@ -50,11 +47,11 @@ public class AddWatchpointActionDelegate extends ActionDelegate implements IView } private void setView(IViewPart view) { - fView = view; + fPart = view; } - protected IViewPart getView() { - return fView; + protected IWorkbenchPart getPart() { + return fPart; } @Override @@ -62,12 +59,17 @@ public class AddWatchpointActionDelegate extends ActionDelegate implements IView fSelection = selection; } + @Override + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + fPart = targetPart; + } + /* (non-Javadoc) * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) */ @Override public void run( IAction action ) { - IToggleBreakpointsTarget toggleTarget = DebugUITools.getToggleBreakpointsTargetManager().getToggleBreakpointsTarget(fView, fSelection); + IToggleBreakpointsTarget toggleTarget = DebugUITools.getToggleBreakpointsTargetManager().getToggleBreakpointsTarget(fPart, fSelection); IToggleBreakpointsTargetCExtension cToggleTarget = null; if (toggleTarget instanceof IToggleBreakpointsTargetCExtension) { cToggleTarget = (IToggleBreakpointsTargetCExtension)toggleTarget; @@ -76,46 +78,9 @@ public class AddWatchpointActionDelegate extends ActionDelegate implements IView } try { - cToggleTarget.createWatchpointsInteractive(fView, fSelection); + cToggleTarget.createWatchpointsInteractive(fPart, fSelection); } catch (CoreException e) { CDebugUIPlugin.errorDialog( ActionMessages.getString( "AddWatchpointActionDelegate1.0" ), e ); //$NON-NLS-1$ } } - - protected void addWatchpoint(boolean write, boolean read, String expression, String memorySpace, BigInteger range) { - if ( getResource() == null ) - return; - try { - CDIDebugModel.createWatchpoint( getSourceHandle(), getResource(), write, read, expression, memorySpace, range, true, 0, "", true ); //$NON-NLS-1$ - } - catch( CoreException ce ) { - CDebugUIPlugin.errorDialog( ActionMessages.getString( "AddWatchpointActionDelegate1.0" ), ce ); //$NON-NLS-1$ - } - } - - private IResource getResource() { - return ResourcesPlugin.getWorkspace().getRoot(); - } - - private String getSourceHandle() { - return ""; //$NON-NLS-1$ - } - - public static ICDIMemorySpaceManagement getMemorySpaceManagement(){ - IAdaptable debugViewElement = DebugUITools.getDebugContext(); - ICDIMemorySpaceManagement memMgr = null; - - if ( debugViewElement != null ) { - ICDebugTarget debugTarget = (ICDebugTarget)debugViewElement.getAdapter(ICDebugTarget.class); - - if ( debugTarget != null ){ - ICDITarget target = (ICDITarget)debugTarget.getAdapter(ICDITarget.class); - - if (target instanceof ICDIMemorySpaceManagement) - memMgr = (ICDIMemorySpaceManagement)target; - } - } - - return memMgr; - } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AddWatchpointOnVariableActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AddWatchpointOnVariableActionDelegate.java new file mode 100644 index 00000000000..a9675a527a4 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AddWatchpointOnVariableActionDelegate.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Nokia 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: + * Nokia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.breakpoints; + + +import org.eclipse.cdt.debug.core.ICWatchpointTarget; +import org.eclipse.cdt.debug.internal.core.CRequest; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeSelection; + +/** + * Invoked when user right clicks on an element in the Variables or Expressions + * view and selects 'Add Watchpoint (C/C++)' Clients can register this action for + * their specific element type which adapts to {@link ICWatchpointTarget}. + * + * + * @noextend This class is not intended to be subclassed by clients. + * @since 7.2 + */ +public class AddWatchpointOnVariableActionDelegate extends AddWatchpointActionDelegate { + + /** The target variable/expression */ + private ICWatchpointTarget fVar; + + /** + * Constructor + */ + public AddWatchpointOnVariableActionDelegate() { + super(); + } + + private class CanCreateWatchpointRequest extends CRequest implements ICWatchpointTarget.CanCreateWatchpointRequest { + boolean fCanCreate; + @Override + public boolean getCanCreate() { + return fCanCreate; + } + @Override + public void setCanCreate(boolean value) { + fCanCreate = value; + } + }; + + /** + * Record the target variable/expression + * + * @see org.eclipse.ui.actions.ActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, + * org.eclipse.jface.viewers.ISelection) + */ + @Override + public void selectionChanged(final IAction action, ISelection selection) { + super.selectionChanged(action, selection); + fVar = null; + if (selection == null || selection.isEmpty()) { + action.setEnabled(false); + return; + } + if (selection instanceof TreeSelection) { + Object obj = ((TreeSelection)selection).getFirstElement(); + fVar = (ICWatchpointTarget)DebugPlugin.getAdapter(obj, ICWatchpointTarget.class); + if (fVar != null) { + final ICWatchpointTarget.CanCreateWatchpointRequest request = new CanCreateWatchpointRequest() { + @Override + public void done() { + action.setEnabled(getCanCreate()); + } + }; + fVar.canSetWatchpoint(request); + return; + } + assert false : "action should not have been available for object " + obj; //$NON-NLS-1$ + } + else if (selection instanceof StructuredSelection) { + // Not sure why, but sometimes we get an extraneous empty StructuredSelection. Seems harmless enough + assert ((StructuredSelection)selection).getFirstElement() == null : "action installed in unexpected type of view/part"; //$NON-NLS-1$ + } + else { + assert false : "action installed in unexpected type of view/part"; //$NON-NLS-1$ + } + action.setEnabled(false); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbVariableVMNode.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbVariableVMNode.java index 2d6eaf50e24..3876ceed5b0 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbVariableVMNode.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbVariableVMNode.java @@ -16,7 +16,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.eclipse.cdt.debug.internal.core.ICWatchpointTarget; +import org.eclipse.cdt.debug.core.ICWatchpointTarget; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.datamodel.DMContexts;