From 1a83c46a2c5eaa61c10dd9da2be7291f75667110 Mon Sep 17 00:00:00 2001 From: Mikhail Khodjaiants Date: Wed, 30 Oct 2002 05:03:21 +0000 Subject: [PATCH] Implementing editing features of the memory view. --- debug/org.eclipse.cdt.debug.core/ChangeLog | 6 + .../cdt/debug/core/IFormattedMemoryBlock.java | 2 + .../debug/core/IFormattedMemoryBlockRow.java | 2 - .../core/model/CFormattedMemoryBlock.java | 110 +++++++----- debug/org.eclipse.cdt.debug.ui/ChangeLog | 6 + .../ui/views/memory/MemoryControlArea.java | 33 ++++ .../ui/views/memory/MemoryPresentation.java | 164 ++++++------------ .../internal/ui/views/memory/MemoryText.java | 96 ++++++++-- 8 files changed, 251 insertions(+), 168 deletions(-) diff --git a/debug/org.eclipse.cdt.debug.core/ChangeLog b/debug/org.eclipse.cdt.debug.core/ChangeLog index cd28df6bf45..16ecf457c30 100644 --- a/debug/org.eclipse.cdt.debug.core/ChangeLog +++ b/debug/org.eclipse.cdt.debug.core/ChangeLog @@ -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 diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/IFormattedMemoryBlock.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/IFormattedMemoryBlock.java index db79891867e..e5fc105585d 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/IFormattedMemoryBlock.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/IFormattedMemoryBlock.java @@ -124,4 +124,6 @@ public interface IFormattedMemoryBlock extends IMemoryBlock boolean isFrozen(); void setFrozen( boolean frozen ); + + boolean isDirty(); } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/IFormattedMemoryBlockRow.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/IFormattedMemoryBlockRow.java index 30835ab89c8..249869a9f4d 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/IFormattedMemoryBlockRow.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/IFormattedMemoryBlockRow.java @@ -34,6 +34,4 @@ public interface IFormattedMemoryBlockRow * @return the ASCII dump for this row */ String getASCII(); - - Integer[] getDirtyItems(); } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CFormattedMemoryBlock.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CFormattedMemoryBlock.java index d87e8e699b9..8f9dbfd7d25 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CFormattedMemoryBlock.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CFormattedMemoryBlock.java @@ -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; + } } diff --git a/debug/org.eclipse.cdt.debug.ui/ChangeLog b/debug/org.eclipse.cdt.debug.ui/ChangeLog index 302577bed2b..9d04914d3dd 100644 --- a/debug/org.eclipse.cdt.debug.ui/ChangeLog +++ b/debug/org.eclipse.cdt.debug.ui/ChangeLog @@ -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 diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/memory/MemoryControlArea.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/memory/MemoryControlArea.java index 0ae818c60f2..e4824a1486c 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/memory/MemoryControlArea.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/memory/MemoryControlArea.java @@ -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 ); + } + } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/memory/MemoryPresentation.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/memory/MemoryPresentation.java index 5d516c62c8a..12df2c75ee2 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/memory/MemoryPresentation.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/memory/MemoryPresentation.java @@ -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; + } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/memory/MemoryText.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/memory/MemoryText.java index 9eef62e031b..3cf57220234 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/memory/MemoryText.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/memory/MemoryText.java @@ -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 ); + } + } }