1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Implementing editing features of the memory view.

This commit is contained in:
Mikhail Khodjaiants 2002-10-30 05:03:21 +00:00
parent f4ed4e4745
commit 1a83c46a2c
8 changed files with 251 additions and 168 deletions

View file

@ -1,3 +1,9 @@
2002-10-29 Mikhail Khodjaiants
Implementing editing features of the memory view.
* IFormattedMemoryBlockRow.java
* IFormattedMemoryBlock.java
* CFormattedMemoryBlock.java
2002-10-28 Mikhail Khodjaiants
Implementing editing features of the memory view.
* IFormattedMemoryBlockRow.java

View file

@ -124,4 +124,6 @@ public interface IFormattedMemoryBlock extends IMemoryBlock
boolean isFrozen();
void setFrozen( boolean frozen );
boolean isDirty();
}

View file

@ -34,6 +34,4 @@ public interface IFormattedMemoryBlockRow
* @return the ASCII dump for this row
*/
String getASCII();
Integer[] getDirtyItems();
}

View file

@ -6,7 +6,6 @@
package org.eclipse.cdt.debug.internal.core.model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
@ -38,7 +37,6 @@ public class CFormattedMemoryBlock extends CDebugElement
private long fAddress;
private String[] fData;
private String fAscii;
private boolean[] fDirtyItems;
/**
* Constructor for CFormattedMemoryBlockRow.
@ -48,8 +46,6 @@ public class CFormattedMemoryBlock extends CDebugElement
fAddress = address;
fData = data;
fAscii = ascii;
fDirtyItems = new boolean[fData.length];
Arrays.fill( fDirtyItems, false );
}
/* (non-Javadoc)
@ -75,30 +71,11 @@ public class CFormattedMemoryBlock extends CDebugElement
{
return fData;
}
protected void setData( int colIndex, String newValue )
{
if ( colIndex < fData.length )
{
fData[colIndex] = newValue;
fDirtyItems[colIndex] = true;
}
}
public Integer[] getDirtyItems()
{
ArrayList list = new ArrayList( fDirtyItems.length );
for ( int i = 0; i < fDirtyItems.length; ++i )
{
if ( fDirtyItems[i] )
list.add( new Integer( i ) );
}
return (Integer[])list.toArray( new Integer[list.size()] );
}
}
private String fAddressExpression;
private ICDIMemoryBlock fCDIMemoryBlock;
private byte[] fBytes = null;
private int fFormat;
private int fWordSize;
private int fNumberOfRows;
@ -107,6 +84,8 @@ public class CFormattedMemoryBlock extends CDebugElement
private char fPaddingChar = '.';
private List fRows = null;
private Long[] fChangedAddresses = new Long[0];
// temporary
private boolean fIsDirty = false;
/**
* Constructor for CFormattedMemoryBlock.
@ -200,7 +179,7 @@ public class CFormattedMemoryBlock extends CDebugElement
{
int offset = 0;
byte[] bytes = getBytes();
while( offset < bytes.length )
while( bytes != null && offset < bytes.length )
{
int length = Math.min( fWordSize * fNumberOfColumns, bytes.length - offset );
fRows.add( new CFormattedMemoryBlockRow( getStartAddress() + offset,
@ -216,7 +195,13 @@ public class CFormattedMemoryBlock extends CDebugElement
}
return (IFormattedMemoryBlockRow[])fRows.toArray( new IFormattedMemoryBlockRow[fRows.size()] );
}
private void resetBytes()
{
fBytes = null;
fIsDirty = false;
}
private void resetRows()
{
fRows = null;
@ -313,18 +298,21 @@ public class CFormattedMemoryBlock extends CDebugElement
*/
public byte[] getBytes() throws DebugException
{
if ( fCDIMemoryBlock != null )
{
try
if ( fBytes == null )
{
if ( fCDIMemoryBlock != null )
{
return fCDIMemoryBlock.getBytes();
}
catch( CDIException e )
{
targetRequestFailed( e.getMessage(), null );
try
{
fBytes = fCDIMemoryBlock.getBytes();
}
catch( CDIException e )
{
targetRequestFailed( e.getMessage(), null );
}
}
}
return new byte[0];
return fBytes;
}
/* (non-Javadoc)
@ -454,6 +442,7 @@ public class CFormattedMemoryBlock extends CDebugElement
private void handleChangedEvent( ICDIMemoryChangedEvent event )
{
resetBytes();
resetRows();
setChangedAddresses( event.getAddresses() );
fireChangeEvent( DebugEvent.CONTENT );
@ -495,15 +484,52 @@ public class CFormattedMemoryBlock extends CDebugElement
*/
public void setItemValue( int index, String newValue ) throws DebugException
{
int rowIndex = index / getNumberOfColumns();
if ( rowIndex < getRows().length )
byte[] bytes = itemToBytes( newValue.toCharArray() );
setBytes( index * getWordSize(), bytes );
fIsDirty = true;
resetRows();
}
private void setBytes( int index, byte[] newBytes )
{
try
{
CFormattedMemoryBlockRow row = (CFormattedMemoryBlockRow)getRows()[rowIndex];
int colIndex = index % getNumberOfColumns();
if ( colIndex < row.getData().length )
byte[] bytes = getBytes();
for ( int i = index; i < index + newBytes.length; ++i )
{
row.setData( colIndex, newValue );
}
bytes[i] = newBytes[i - index];
}
}
catch( DebugException e )
{
}
}
private byte[] itemToBytes( char[] chars )
{
switch( getFormat() )
{
case IFormattedMemoryBlock.MEMORY_FORMAT_HEX:
return hexItemToBytes( chars );
}
return new byte[0];
}
private byte[] hexItemToBytes( char[] chars )
{
byte[] result = new byte[chars.length / 2];
for ( int i = 0; i < result.length; ++i )
{
result[i] = CDebugUtils.textToByte( new char[] { chars[2 * i], chars[2 * i + 1] } );
}
return result;
}
/**
* @see org.eclipse.cdt.debug.core.IFormattedMemoryBlock#isDirty()
*/
public boolean isDirty()
{
return fIsDirty;
}
}

View file

@ -1,3 +1,9 @@
2002-10-29 Mikhail Khodjaiants
Implementing editing features of the memory view.
* MemoryPresentation.java
* MemoryControlArea.java
* MemoryText.java
2002-10-28 Mikhail Khodjaiants
Implementing editing features of the memory view.
* MemoryPresentation.java

View file

@ -15,6 +15,8 @@ import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.layout.GridData;
@ -338,4 +340,35 @@ public class MemoryControlArea extends Composite
fAddressText.setText( "" );
handleAddressEnter();
}
/**
* @see org.eclipse.swt.widgets.Widget#dispose()
*/
public void dispose()
{
if ( getPresentation() != null )
{
getPresentation().dispose();
}
super.dispose();
}
protected String getTitle()
{
if ( getParent() instanceof CTabFolder )
{
CTabItem[] tabItems = ((CTabFolder)getParent()).getItems();
return tabItems[fIndex].getText();
}
return "";
}
protected void setTitle( String title )
{
if ( getParent() instanceof CTabFolder )
{
CTabItem[] tabItems = ((CTabFolder)getParent()).getItems();
tabItems[fIndex].setText( title );
}
}
}

View file

@ -39,7 +39,7 @@ public class MemoryPresentation
private List fChangedZones;
private boolean fDisplayAscii = true;
/**
* Constructor for MemoryPresentation.
*/
@ -121,35 +121,6 @@ public class MemoryPresentation
return (Point[])fChangedZones.toArray( new Point[fChangedZones.size()] );
}
public Point[] getDirtyZones()
{
ArrayList dirtyZones = new ArrayList();
if ( fBlock != null )
{
IFormattedMemoryBlockRow[] rows = fBlock.getRows();
for ( int i = 0; i < rows.length; ++i )
{
int rowOffset = i * getRowLength();
Integer[] dirtyItems = rows[i].getDirtyItems();
for ( int j = 0; j < dirtyItems.length; ++j )
{
int offset = rowOffset +
getAddressLength() + INTERVAL_BETWEEN_ADDRESS_AND_DATA +
dirtyItems[j].intValue() * (getDataItemLength() + INTERVAL_BETWEEN_DATA_ITEMS);
dirtyZones.add( new Point( offset, offset + getDataItemLength() ) );
if ( displayASCII() )
{
offset = rowOffset +
getAddressLength() + INTERVAL_BETWEEN_ADDRESS_AND_DATA +
getNumberOfDataItemsInRow() * (getDataItemLength() + INTERVAL_BETWEEN_DATA_ITEMS);
dirtyZones.add( new Point( offset, offset + (getDataItemLength() / 2) ) );
}
}
}
}
return (Point[])dirtyZones.toArray( new Point[dirtyZones.size()] );
}
public String getStartAddress()
{
return ( fBlock != null ) ? getAddressString( fBlock.getStartAddress() ) : "";
@ -192,85 +163,6 @@ public class MemoryPresentation
return result.toString();
}
/*
private String getItemString( int offset )
{
byte[] data = getDataBytes();
String item = new String( data, offset, getSize() );
String result = "";
switch( fFormat )
{
case ICDebugUIInternalConstants.MEMORY_FORMAT_HEX:
for ( int i = 0; i < getSize(); ++i )
result += new String( charToBytes( item.charAt( i ) ) );
break;
case ICDebugUIInternalConstants.MEMORY_FORMAT_BINARY:
for ( int i = 0; i < getSize(); ++i )
result += prepend( Integer.toBinaryString( data[offset + i] ), '0', 8 );
break;
case ICDebugUIInternalConstants.MEMORY_FORMAT_OCTAL:
for ( int i = 0; i < getSize(); ++i )
result += Integer.toOctalString( data[offset + i] );
break;
}
return result;
}
private String getASCIIString( int offset )
{
byte[] data = getDataBytes();
char[] ascii = new char[getBytesPerRow()];
for ( int i = 0; i < ascii.length; ++i )
{
ascii[i] = ( data.length > offset + i ) ? getChar( data[offset + i] ) : fNotAvailableChar;
}
return new String( ascii );
}
private char getChar( byte charByte )
{
char ch = (char)charByte;
if ( ch == fNotAvailableChar )
return fNotAvailableChar;
return ( Character.isISOControl( ch ) ) ? fPaddingChar : ch;
}
private char[] charToBytes( char ch )
{
return new char[]{ charFromByte( (char)(ch >>> 4) ),
charFromByte( (char)(ch & 0x0f) ) };
}
private char charFromByte( char value )
{
if ( value >= 0x0 && value <= 0x9 )
return (char)(value + '0');
if ( value >= 0xa && value <= 0xf )
return (char)(value - 0xa + 'a');
return '0';
}
private byte[] getDataBytes()
{
return new byte[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
/*
byte[] result = new byte[0];
if ( fBlock != null )
{
try
{
result = fBlock.getBytes();
}
catch( DebugException e )
{
// ignore
}
}
return result;
*/
/*
}
*/
private String resize( String item, char ch, int size )
{
char[] chars = new char[size - item.length()];
@ -356,6 +248,13 @@ public class MemoryPresentation
return getMemoryBlock().getNumberOfColumns();
return 0;
}
private char getPaddingCharacter()
{
if ( getMemoryBlock() != null )
return getMemoryBlock().getPaddingCharacter();
return '.';
}
protected boolean displayASCII()
{
@ -470,8 +369,9 @@ public class MemoryPresentation
return false;
}
protected void textChanged( int offset, char newChar, char[] replacedText )
protected MemoryText.TextReplacement[] textChanged( int offset, char newChar, char[] replacedText )
{
ArrayList list = new ArrayList();
if ( getMemoryBlock() != null )
{
int index = getDataItemIndex( offset );
@ -489,7 +389,14 @@ public class MemoryPresentation
}
try
{
getMemoryBlock().setItemValue( index, new String( chars ) );
String text = new String( chars );
getMemoryBlock().setItemValue( index, text );
list.add( new MemoryText.TextReplacement( getDataItemOffset( index ), text ) );
if ( displayASCII() )
{
// Ascii is enabled only when the word size is one byte
list.add( getAsciiTextReplacement( index, chars ) );
}
}
catch( DebugException e )
{
@ -497,6 +404,7 @@ public class MemoryPresentation
}
}
}
return (MemoryText.TextReplacement[])list.toArray( new MemoryText.TextReplacement[list.size()] );
}
private int getDataItemIndex( int offset )
@ -554,4 +462,38 @@ public class MemoryPresentation
}
return -1;
}
private MemoryText.TextReplacement getAsciiTextReplacement( int itemIndex, char[] chars )
{
int row = itemIndex / getNumberOfDataItemsInRow();
int col = itemIndex % getNumberOfDataItemsInRow();
int offset = row * getRowLength() +
getAddressLength() + INTERVAL_BETWEEN_ADDRESS_AND_DATA +
getNumberOfDataItemsInRow() * (getDataItemLength() + INTERVAL_BETWEEN_DATA_ITEMS) +
INTERVAL_BETWEEN_DATA_AND_ASCII + col;
byte newValue = CDebugUtils.textToByte( chars );
char ch = ( Character.isISOControl( (char)newValue ) || newValue < 0 ) ? getPaddingCharacter() : (char)newValue;
return new MemoryText.TextReplacement( offset, new String( new char[]{ ch } ) );
}
public void dispose()
{
if ( fAddressZones != null )
{
fAddressZones.clear();
}
if ( fChangedZones != null )
{
fChangedZones.clear();
}
}
protected boolean isDirty()
{
if ( getMemoryBlock() != null )
{
return getMemoryBlock().isDirty();
}
return false;
}
}

View file

@ -32,9 +32,42 @@ import org.eclipse.swt.widgets.Control;
* @since Jul 25, 2002
*/
public class MemoryText
{
{
/**
*
* The instance of this class specifies the text replacement
* that has to be applied to the StyledText widget.
*
* @since Oct 29, 2002
*/
public static class TextReplacement
{
private int fStart;
private String fText;
/**
* Constructor for TextReplacement.
*/
public TextReplacement( int start, String text )
{
fStart = start;
fText = text;
}
public int getStart()
{
return fStart;
}
public String getText()
{
return fText;
}
}
private StyledText fText = null;
private MemoryPresentation fPresentation = null;
private boolean fUpdating = false;
/**
* Constructor for MemoryText.
@ -81,13 +114,15 @@ public class MemoryText
protected void handleExtendedModify( ExtendedModifyEvent event )
{
if ( fUpdating )
return;
if ( event.length != 1 )
return;
TextReplacement[] trs = fPresentation.textChanged( event.start,
fText.getText().charAt( event.start ),
event.replacedText.toCharArray() );
int caretOffset = fText.getCaretOffset();
fPresentation.textChanged( event.start,
fText.getText().charAt( event.start ),
event.replacedText.toCharArray() );
refresh();
update( trs );
fText.setCaretOffset( caretOffset );
}
@ -114,15 +149,8 @@ public class MemoryText
getAddressColor(),
getBackgroundColor() ) );
}
zones = fPresentation.getDirtyZones();
for ( int i = 0; i < zones.length; ++i )
{
fText.setStyleRange( new StyleRange( zones[i].x,
zones[i].y - zones[i].x + 1,
getDirtyColor(),
getBackgroundColor() ) );
}
fText.redraw();
updateTitle();
}
private void refresh( Point[] zones, String[] items )
@ -133,12 +161,15 @@ public class MemoryText
fText.replaceTextRange( zones[i].x,
zones[i].y - zones[i].x + 1,
items[i] );
/*
fText.setStyleRange( new StyleRange( zones[i].x,
zones[i].y - zones[i].x + 1,
getDirtyColor(),
getBackgroundColor() ) );
*/
fText.redrawRange( zones[i].x, zones[i].y - zones[i].x + 1, false );
}
updateTitle();
}
protected void handleVerifyKey( VerifyEvent event )
@ -237,6 +268,7 @@ public class MemoryText
public void setDirtyColor()
{
/*
Point[] zones = fPresentation.getDirtyZones();
for ( int i = 0; i < zones.length; ++i )
{
@ -245,6 +277,7 @@ public class MemoryText
getDirtyColor(),
getBackgroundColor() ) );
}
*/
}
protected void setEditable( boolean editable )
@ -261,4 +294,41 @@ public class MemoryText
{
return fText;
}
protected void update( TextReplacement[] trs )
{
fUpdating = true;
for ( int i = 0; i < trs.length; ++i )
{
fText.replaceTextRange( trs[i].getStart(),
trs[i].getText().length(),
trs[i].getText() );
/*
fText.setStyleRange( new StyleRange( trs[i].getStart(),
trs[i].getText().length(),
getDirtyColor(),
getBackgroundColor() ) );
*/
fText.redrawRange( trs[i].getStart(), trs[i].getText().length(), false );
}
fUpdating = false;
updateTitle();
}
private void updateTitle()
{
if ( fText.getParent() instanceof MemoryControlArea )
{
String title = ((MemoryControlArea)fText.getParent()).getTitle();
if ( title.charAt( 0 ) == '*' )
{
title = title.substring( 1 );
}
if ( fPresentation.isDirty() )
{
title = '*' + title;
}
((MemoryControlArea)fText.getParent()).setTitle( title );
}
}
}