blob: b61be612deda7b6d52155e9dadd154149256b047 [file] [log] [blame]
/*
*(c) Copyright QNX Software Systems Ltd. 2002.
* All Rights Reserved.
*
*/
package org.eclipse.cdt.debug.internal.ui.actions;
import java.util.Iterator;
import org.eclipse.cdt.debug.internal.ui.CDebugImages;
import org.eclipse.cdt.debug.internal.ui.ICDebugHelpContextIds;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IValueModification;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TreeEditor;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.actions.SelectionProviderAction;
import org.eclipse.ui.help.WorkbenchHelp;
/**
*
* Enter type comment.
*
* @since Sep 16, 2002
*/
public class ChangeRegisterValueAction extends SelectionProviderAction
{
protected Tree fTree;
protected TreeEditor fTreeEditor;
protected Composite fComposite;
protected Label fEditorLabel;
protected Text fEditorText;
protected IVariable fVariable;
protected boolean fKeyReleased = false;
/**
* Constructor for ChangeRegisterValueAction.
* @param provider
* @param text
*/
public ChangeRegisterValueAction( Viewer viewer )
{
super( viewer, "Change Register Value" );
setDescription( "Change Register Value" );
CDebugImages.setLocalImageDescriptors( this, CDebugImages.IMG_LCL_CHANGE_REGISTER_VALUE );
fTree = ((TreeViewer)viewer).getTree();
fTreeEditor = new TreeEditor( fTree );
WorkbenchHelp.setHelp( this, ICDebugHelpContextIds.CHANGE_REGISTER_VALUE_ACTION );
}
/**
* Edit the variable value with an inline text editor.
*/
protected void doActionPerformed( final IVariable variable )
{
IWorkbenchWindow window = CDebugUIPlugin.getActiveWorkbenchWindow();
if ( window == null )
{
return;
}
final Shell activeShell = window.getShell();
// If a previous edit is still in progress, finish it
if ( fEditorText != null )
{
saveChangesAndCleanup( fVariable, activeShell );
}
fVariable = variable;
// Use a Composite containing a Label and a Text. This allows us to edit just
// the value, while still showing the variable name.
fComposite = new Composite( fTree, SWT.NONE );
fComposite.setBackground( fTree.getBackground() );
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginHeight = 0;
layout.marginWidth = 0;
fComposite.setLayout( layout );
fEditorLabel = new Label( fComposite, SWT.LEFT );
fEditorLabel.setLayoutData( new GridData( GridData.FILL_VERTICAL ) );
// Fix for bug 1766. Border behavior on Windows & Linux for text
// fields is different. On Linux, you always get a border, on Windows,
// you don't. Specifying a border on Linux results in the characters
// getting pushed down so that only there very tops are visible. Thus,
// we have to specify different style constants for the different platforms.
int textStyles = SWT.SINGLE | SWT.LEFT;
if ( SWT.getPlatform().equals( "win32" ) )
{ //$NON-NLS-1$
textStyles |= SWT.BORDER;
}
fEditorText = new Text( fComposite, textStyles );
fEditorText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL ) );
String valueString = ""; //$NON-NLS-1$
try
{
valueString = fVariable.getValue().getValueString();
}
catch( DebugException de )
{
CDebugUIPlugin.errorDialog( "Setting the register value failed.", de );
}
TreeItem[] selectedItems = fTree.getSelection();
fTreeEditor.horizontalAlignment = SWT.LEFT;
fTreeEditor.grabHorizontal = true;
fTreeEditor.setEditor( fComposite, selectedItems[0] );
// There is no API on the model presentation to get just the variable name,
// so we have to make do with just calling IVariable.getName()
String varName = ""; //$NON-NLS-1$
try
{
varName = fVariable.getName();
}
catch (DebugException de)
{
CDebugUIPlugin.errorDialog( "Setting the register value failed.", de );
}
fEditorLabel.setText( varName + "=" ); //$NON-NLS-1$
fEditorText.setText( valueString );
fEditorText.selectAll();
fComposite.layout( true );
fComposite.setVisible( true );
fEditorText.setFocus();
// CR means commit the changes, ESC means abort changing the value
fEditorText.addKeyListener(
new KeyAdapter()
{
public void keyReleased( KeyEvent event )
{
if ( event.character == SWT.CR )
{
if ( fKeyReleased )
{
saveChangesAndCleanup( fVariable, activeShell );
}
else
{
cleanup();
return;
}
}
if ( event.character == SWT.ESC )
{
cleanup();
return;
}
fKeyReleased = true;
}
} );
// If the focus is lost, then act as if user hit CR and commit changes
fEditorText.addFocusListener(
new FocusAdapter()
{
public void focusLost( FocusEvent fe )
{
if ( fKeyReleased )
{
saveChangesAndCleanup( fVariable, activeShell );
}
else
{
cleanup();
}
}
} );
}
/**
* If the new value validates, save it, and dispose the text widget,
* otherwise sound the system bell and leave the user in the editor.
*/
protected void saveChangesAndCleanup( IVariable variable, Shell shell )
{
String newValue = fEditorText.getText();
try
{
if ( !variable.verifyValue( newValue ) )
{
shell.getDisplay().beep();
return;
}
variable.setValue( newValue );
}
catch( DebugException de )
{
CDebugUIPlugin.errorDialog( "Setting the register value failed.", de );
}
cleanup();
}
/**
* Tidy up the widgets that were used
*/
protected void cleanup()
{
fKeyReleased = false;
if ( fEditorText != null )
{
fEditorText.dispose();
fEditorText = null;
fVariable = null;
fTreeEditor.setEditor( null, null );
fComposite.setVisible( false );
}
}
/**
* Updates the enabled state of this action based
* on the selection
*/
protected void update( IStructuredSelection sel )
{
Iterator iter = sel.iterator();
if (iter.hasNext())
{
Object object = iter.next();
if ( object instanceof IValueModification )
{
IValueModification varMod = (IValueModification)object;
if ( !varMod.supportsValueModification() )
{
setEnabled( false );
return;
}
setEnabled( !iter.hasNext() );
return;
}
}
setEnabled( false );
}
/**
* @see Action
*/
public void run()
{
Iterator iterator = getStructuredSelection().iterator();
doActionPerformed( (IVariable)iterator.next() );
}
/**
* @see SelectionProviderAction
*/
public void selectionChanged( IStructuredSelection sel )
{
update( sel );
}
}