mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
[230262] Implement Memory Change Trails
This commit is contained in:
parent
237bb02706
commit
c289fa0b9b
8 changed files with 248 additions and 104 deletions
|
@ -17,6 +17,7 @@ import java.math.BigInteger;
|
||||||
import org.eclipse.debug.core.DebugException;
|
import org.eclipse.debug.core.DebugException;
|
||||||
import org.eclipse.debug.core.model.MemoryByte;
|
import org.eclipse.debug.core.model.MemoryByte;
|
||||||
import org.eclipse.swt.events.PaintEvent;
|
import org.eclipse.swt.events.PaintEvent;
|
||||||
|
import org.eclipse.swt.graphics.Color;
|
||||||
import org.eclipse.swt.graphics.GC;
|
import org.eclipse.swt.graphics.GC;
|
||||||
import org.eclipse.swt.graphics.Point;
|
import org.eclipse.swt.graphics.Point;
|
||||||
|
|
||||||
|
@ -102,8 +103,8 @@ public class DataPane extends AbstractPane
|
||||||
}
|
}
|
||||||
//else
|
//else
|
||||||
{
|
{
|
||||||
if(bytes[i] instanceof TraditionalMemoryByte)
|
// if(bytes[i] instanceof TraditionalMemoryByte)
|
||||||
bytesToSet[i].setEdited(((TraditionalMemoryByte) bytes[i]).isEdited());
|
// bytesToSet[i].setEdited(((TraditionalMemoryByte) bytes[i]).isEdited());
|
||||||
bytesToSet[i].setChanged(bytes[i].isChanged());
|
bytesToSet[i].setChanged(bytes[i].isChanged());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,7 +273,7 @@ public class DataPane extends AbstractPane
|
||||||
* fRendering.getColumnCount() + col)
|
* fRendering.getColumnCount() + col)
|
||||||
* fRendering.getAddressesPerColumn()));
|
* fRendering.getAddressesPerColumn()));
|
||||||
|
|
||||||
MemoryByte bytes[] = fRendering.getBytes(cellAddress,
|
TraditionalMemoryByte bytes[] = fRendering.getBytes(cellAddress,
|
||||||
fRendering.getBytesPerColumn());
|
fRendering.getBytesPerColumn());
|
||||||
|
|
||||||
if(fRendering.getSelection().isSelected(cellAddress))
|
if(fRendering.getSelection().isSelected(cellAddress))
|
||||||
|
@ -293,7 +294,6 @@ public class DataPane extends AbstractPane
|
||||||
|
|
||||||
// Allow subclasses to override this method to do their own coloring
|
// Allow subclasses to override this method to do their own coloring
|
||||||
applyCustomColor(gc, bytes, col);
|
applyCustomColor(gc, bytes, col);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gc.drawText(getCellText(bytes), cellWidth * col
|
gc.drawText(getCellText(bytes), cellWidth * col
|
||||||
|
@ -337,31 +337,46 @@ public class DataPane extends AbstractPane
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow subclasses to override this method to do their own coloring
|
// Allow subclasses to override this method to do their own coloring
|
||||||
protected void applyCustomColor(GC gc, MemoryByte bytes[], int col)
|
protected void applyCustomColor(GC gc, TraditionalMemoryByte bytes[], int col)
|
||||||
{
|
{
|
||||||
// TODO consider adding finer granularity?
|
// TODO consider adding finer granularity?
|
||||||
boolean anyByteChanged = false;
|
boolean anyByteEditing = false;
|
||||||
for(int n = 0; n < bytes.length && !anyByteChanged; n++)
|
for(int n = 0; n < bytes.length && !anyByteEditing; n++)
|
||||||
if(bytes[n].isChanged())
|
if(bytes[n] instanceof TraditionalMemoryByte)
|
||||||
anyByteChanged = true;
|
if(((TraditionalMemoryByte) bytes[n]).isEdited())
|
||||||
|
anyByteEditing = true;
|
||||||
|
|
||||||
// TODO consider adding finer granularity?
|
if(isOdd(col))
|
||||||
boolean anyByteEditing = false;
|
|
||||||
for(int n = 0; n < bytes.length && !anyByteEditing; n++)
|
|
||||||
if(bytes[n] instanceof TraditionalMemoryByte)
|
|
||||||
if(((TraditionalMemoryByte) bytes[n]).isEdited())
|
|
||||||
anyByteEditing = true;
|
|
||||||
|
|
||||||
if(anyByteEditing)
|
|
||||||
gc.setForeground(fRendering.getTraditionalRendering().getColorEdit());
|
|
||||||
else if(anyByteChanged)
|
|
||||||
gc.setForeground(fRendering.getTraditionalRendering().getColorChanged());
|
|
||||||
else if(isOdd(col))
|
|
||||||
gc.setForeground(fRendering.getTraditionalRendering().getColorText());
|
gc.setForeground(fRendering.getTraditionalRendering().getColorText());
|
||||||
else
|
else
|
||||||
gc.setForeground(fRendering.getTraditionalRendering().getColorTextAlternate());
|
gc.setForeground(fRendering.getTraditionalRendering().getColorTextAlternate());
|
||||||
|
|
||||||
gc.setBackground(fRendering.getTraditionalRendering().getColorBackground());
|
gc.setBackground(fRendering.getTraditionalRendering().getColorBackground());
|
||||||
|
|
||||||
|
if(anyByteEditing)
|
||||||
|
{
|
||||||
|
gc.setForeground(fRendering.getTraditionalRendering().getColorEdit());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boolean isColored = false;
|
||||||
|
for(int i = 0; i < fRendering.getHistoryDepth() && !isColored; i++)
|
||||||
|
{
|
||||||
|
// TODO consider adding finer granularity?
|
||||||
|
for(int n = 0; n < bytes.length; n++)
|
||||||
|
{
|
||||||
|
if(bytes[n].isChanged(i))
|
||||||
|
{
|
||||||
|
if(i == 0)
|
||||||
|
gc.setForeground(fRendering.getTraditionalRendering().getColorsChanged()[i]);
|
||||||
|
else
|
||||||
|
gc.setBackground(fRendering.getTraditionalRendering().getColorsChanged()[i]);
|
||||||
|
isColored = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@ public interface IViewportCache {
|
||||||
|
|
||||||
public void dispose();
|
public void dispose();
|
||||||
public void refresh();
|
public void refresh();
|
||||||
public MemoryByte[] getBytes(BigInteger address, int bytesRequested) throws DebugException;
|
public TraditionalMemoryByte[] getBytes(BigInteger address, int bytesRequested) throws DebugException;
|
||||||
public void archiveDeltas();
|
public void archiveDeltas();
|
||||||
public void setEditedValue(BigInteger address, MemoryByte[] bytes);
|
public void setEditedValue(BigInteger address, TraditionalMemoryByte[] bytes);
|
||||||
public void clearEditBuffer();
|
public void clearEditBuffer();
|
||||||
public void writeEditBuffer();
|
public void writeEditBuffer();
|
||||||
public boolean containsEditedCell(BigInteger address);
|
public boolean containsEditedCell(BigInteger address);
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
|
||||||
import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil;
|
import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil;
|
||||||
import org.eclipse.debug.internal.ui.views.memory.renderings.GoToAddressComposite;
|
import org.eclipse.debug.internal.ui.views.memory.renderings.GoToAddressComposite;
|
||||||
import org.eclipse.jface.dialogs.IDialogConstants;
|
import org.eclipse.jface.dialogs.IDialogConstants;
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
import org.eclipse.jface.resource.JFaceResources;
|
import org.eclipse.jface.resource.JFaceResources;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.dnd.Clipboard;
|
import org.eclipse.swt.dnd.Clipboard;
|
||||||
|
@ -106,7 +107,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
private boolean fIsTargetLittleEndian = false;
|
private boolean fIsTargetLittleEndian = false;
|
||||||
|
|
||||||
private boolean fIsDisplayLittleEndian = false;
|
private boolean fIsDisplayLittleEndian = false;
|
||||||
|
|
||||||
// constants used to identify radix
|
// constants used to identify radix
|
||||||
public final static int RADIX_HEX = 1;
|
public final static int RADIX_HEX = 1;
|
||||||
|
|
||||||
|
@ -482,6 +483,16 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
{
|
{
|
||||||
return fSelection;
|
return fSelection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected int getHistoryDepth()
|
||||||
|
{
|
||||||
|
return fViewportCache.getHistoryDepth();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setHistoryDepth(int depth)
|
||||||
|
{
|
||||||
|
fViewportCache.setHistoryDepth(depth);
|
||||||
|
}
|
||||||
|
|
||||||
public void logError(String message, Exception e)
|
public void logError(String message, Exception e)
|
||||||
{
|
{
|
||||||
|
@ -609,7 +620,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
return fViewportCache;
|
return fViewportCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemoryByte[] getBytes(BigInteger address, int bytes)
|
public TraditionalMemoryByte[] getBytes(BigInteger address, int bytes)
|
||||||
throws DebugException
|
throws DebugException
|
||||||
{
|
{
|
||||||
return getViewportCache().getBytes(address, bytes);
|
return getViewportCache().getBytes(address, bytes);
|
||||||
|
@ -652,7 +663,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,7 +673,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
|
|
||||||
BigInteger end;
|
BigInteger end;
|
||||||
|
|
||||||
MemoryByte[] bytes;
|
TraditionalMemoryByte[] bytes;
|
||||||
|
|
||||||
public MemoryUnit clone()
|
public MemoryUnit clone()
|
||||||
{
|
{
|
||||||
|
@ -670,9 +681,9 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
|
|
||||||
b.start = this.start;
|
b.start = this.start;
|
||||||
b.end = this.end;
|
b.end = this.end;
|
||||||
b.bytes = new MemoryByte[this.bytes.length];
|
b.bytes = new TraditionalMemoryByte[this.bytes.length];
|
||||||
for(int i = 0; i < this.bytes.length; i++)
|
for(int i = 0; i < this.bytes.length; i++)
|
||||||
b.bytes[i] = new MemoryByte(this.bytes[i].getValue());
|
b.bytes[i] = new TraditionalMemoryByte(this.bytes[i].getValue());
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
@ -694,8 +705,10 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
|
|
||||||
protected MemoryUnit fCache = null;
|
protected MemoryUnit fCache = null;
|
||||||
|
|
||||||
protected MemoryUnit fHistoryCache = null;
|
protected MemoryUnit fHistoryCache[] = new MemoryUnit[0];
|
||||||
|
|
||||||
|
protected int fHistoryDepth = 0;
|
||||||
|
|
||||||
public ViewportCache()
|
public ViewportCache()
|
||||||
{
|
{
|
||||||
start();
|
start();
|
||||||
|
@ -709,6 +722,17 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
this.notify();
|
this.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getHistoryDepth()
|
||||||
|
{
|
||||||
|
return fHistoryDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHistoryDepth(int depth)
|
||||||
|
{
|
||||||
|
fHistoryDepth = depth;
|
||||||
|
fHistoryCache = new MemoryUnit[fHistoryDepth];
|
||||||
|
}
|
||||||
|
|
||||||
public void refresh()
|
public void refresh()
|
||||||
{
|
{
|
||||||
|
@ -737,8 +761,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
private void queueRequest(BigInteger startAddress, BigInteger endAddress)
|
private void queueRequest(BigInteger startAddress, BigInteger endAddress)
|
||||||
{
|
{
|
||||||
AddressPair pair = new AddressPair(startAddress, endAddress);
|
AddressPair pair = new AddressPair(startAddress, endAddress);
|
||||||
if(!pair.equals(fLastQueued))
|
queue(pair);
|
||||||
queue(pair);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void queueRequestArchiveDeltas()
|
private void queueRequestArchiveDeltas()
|
||||||
|
@ -751,8 +774,11 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
{
|
{
|
||||||
synchronized(fQueue)
|
synchronized(fQueue)
|
||||||
{
|
{
|
||||||
fQueue.addElement(element);
|
if(!(fQueue.size() > 0 && element.equals(fLastQueued)))
|
||||||
fLastQueued = element;
|
{
|
||||||
|
fQueue.addElement(element);
|
||||||
|
fLastQueued = element;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
synchronized(this)
|
synchronized(this)
|
||||||
{
|
{
|
||||||
|
@ -789,7 +815,10 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
}
|
}
|
||||||
if(archiveDeltas)
|
if(archiveDeltas)
|
||||||
{
|
{
|
||||||
fHistoryCache = fCache.clone();
|
for(int i = fViewportCache.getHistoryDepth() - 1; i > 0; i--)
|
||||||
|
fHistoryCache[i] = fHistoryCache[i - 1];
|
||||||
|
|
||||||
|
fHistoryCache[0] = fCache.clone();
|
||||||
}
|
}
|
||||||
else if(pair != null)
|
else if(pair != null)
|
||||||
{
|
{
|
||||||
|
@ -837,9 +866,9 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
final MemoryByte readBytes[] = memoryBlock
|
final MemoryByte readBytes[] = memoryBlock
|
||||||
.getBytesFromAddress(startAddress, units);
|
.getBytesFromAddress(startAddress, units);
|
||||||
|
|
||||||
MemoryByte cachedBytes[] = new MemoryByte[readBytes.length];
|
TraditionalMemoryByte cachedBytes[] = new TraditionalMemoryByte[readBytes.length];
|
||||||
for(int i = 0; i < readBytes.length; i++)
|
for(int i = 0; i < readBytes.length; i++)
|
||||||
cachedBytes[i] = new MemoryByte(readBytes[i].getValue(), readBytes[i].getFlags());
|
cachedBytes[i] = new TraditionalMemoryByte(readBytes[i].getValue(), readBytes[i].getFlags());
|
||||||
|
|
||||||
// derive the target endian from the read MemoryBytes.
|
// derive the target endian from the read MemoryBytes.
|
||||||
if (cachedBytes.length > 0) {
|
if (cachedBytes.length > 0) {
|
||||||
|
@ -855,7 +884,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
if(addressableSize.compareTo(BigInteger.ONE) != 0)
|
if(addressableSize.compareTo(BigInteger.ONE) != 0)
|
||||||
{
|
{
|
||||||
int unitSize = addressableSize.intValue();
|
int unitSize = addressableSize.intValue();
|
||||||
MemoryByte cachedBytesAsByteSequence[] = new MemoryByte[cachedBytes.length];
|
TraditionalMemoryByte cachedBytesAsByteSequence[] = new TraditionalMemoryByte[cachedBytes.length];
|
||||||
for(int unit = 0; unit < units; unit++)
|
for(int unit = 0; unit < units; unit++)
|
||||||
{
|
{
|
||||||
for(int unitbyte = 0; unitbyte < unitSize; unitbyte++)
|
for(int unitbyte = 0; unitbyte < unitSize; unitbyte++)
|
||||||
|
@ -867,40 +896,43 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final MemoryByte[] cachedBytesFinal = cachedBytes;
|
final TraditionalMemoryByte[] cachedBytesFinal = cachedBytes;
|
||||||
Display.getDefault().asyncExec(new Runnable()
|
Display.getDefault().asyncExec(new Runnable()
|
||||||
{
|
{
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
// generate deltas
|
// generate deltas
|
||||||
if(fHistoryCache != null && fHistoryCache.isValid())
|
for(int historyIndex = 0; historyIndex < getHistoryDepth(); historyIndex++)
|
||||||
{
|
{
|
||||||
BigInteger maxStart = startAddress
|
if(fHistoryCache[historyIndex] != null && fHistoryCache[historyIndex].isValid())
|
||||||
.max(fHistoryCache.start);
|
{
|
||||||
BigInteger minEnd = endAddress
|
BigInteger maxStart = startAddress
|
||||||
.min(fHistoryCache.end).subtract(
|
.max(fHistoryCache[historyIndex].start);
|
||||||
BigInteger.valueOf(1));
|
BigInteger minEnd = endAddress
|
||||||
|
.min(fHistoryCache[historyIndex].end).subtract(
|
||||||
BigInteger overlapLength = minEnd
|
BigInteger.valueOf(1));
|
||||||
.subtract(maxStart);
|
|
||||||
if(overlapLength.compareTo(BigInteger.valueOf(0)) > 0)
|
BigInteger overlapLength = minEnd
|
||||||
{
|
.subtract(maxStart);
|
||||||
// there is overlap
|
if(overlapLength.compareTo(BigInteger.valueOf(0)) > 0)
|
||||||
|
{
|
||||||
int offsetIntoOld = maxStart.subtract(
|
// there is overlap
|
||||||
fHistoryCache.start).intValue();
|
|
||||||
int offsetIntoNew = maxStart.subtract(
|
int offsetIntoOld = maxStart.subtract(
|
||||||
startAddress).intValue();
|
fHistoryCache[historyIndex].start).intValue();
|
||||||
|
int offsetIntoNew = maxStart.subtract(
|
||||||
for(int i = overlapLength.intValue(); i >= 0; i--)
|
startAddress).intValue();
|
||||||
{
|
|
||||||
cachedBytesFinal[offsetIntoNew + i]
|
for(int i = overlapLength.intValue(); i >= 0; i--)
|
||||||
.setChanged(cachedBytesFinal[offsetIntoNew
|
{
|
||||||
+ i].getValue() != fHistoryCache.bytes[offsetIntoOld
|
cachedBytesFinal[offsetIntoNew + i]
|
||||||
+ i].getValue());
|
.setChanged(historyIndex, cachedBytesFinal[offsetIntoNew
|
||||||
}
|
+ i].getValue() != fHistoryCache[historyIndex].bytes[offsetIntoOld
|
||||||
}
|
+ i].getValue());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fCache = new MemoryUnit();
|
fCache = new MemoryUnit();
|
||||||
fCache.start = startAddress;
|
fCache.start = startAddress;
|
||||||
|
@ -910,8 +942,8 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
// If the history does not exist, populate the history with the just populated cache. This solves the
|
// If the history does not exist, populate the history with the just populated cache. This solves the
|
||||||
// use case of 1) connect to target; 2) edit memory before the first suspend debug event; 3) paint
|
// use case of 1) connect to target; 2) edit memory before the first suspend debug event; 3) paint
|
||||||
// differences in changed color.
|
// differences in changed color.
|
||||||
if(fHistoryCache == null)
|
if(fHistoryCache[0] == null)
|
||||||
fHistoryCache = fCache.clone();
|
fHistoryCache[0] = fCache.clone();
|
||||||
|
|
||||||
Rendering.this.redrawPanes();
|
Rendering.this.redrawPanes();
|
||||||
}
|
}
|
||||||
|
@ -927,7 +959,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
}
|
}
|
||||||
|
|
||||||
// bytes will be fetched from cache
|
// bytes will be fetched from cache
|
||||||
public MemoryByte[] getBytes(BigInteger address, int bytesRequested)
|
public TraditionalMemoryByte[] getBytes(BigInteger address, int bytesRequested)
|
||||||
throws DebugException
|
throws DebugException
|
||||||
{
|
{
|
||||||
assert Thread.currentThread().equals(
|
assert Thread.currentThread().equals(
|
||||||
|
@ -952,7 +984,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
if(contains)
|
if(contains)
|
||||||
{
|
{
|
||||||
int offset = address.subtract(fCache.start).intValue();
|
int offset = address.subtract(fCache.start).intValue();
|
||||||
MemoryByte bytes[] = new MemoryByte[bytesRequested];
|
TraditionalMemoryByte bytes[] = new TraditionalMemoryByte[bytesRequested];
|
||||||
for(int i = 0; i < bytes.length; i++)
|
for(int i = 0; i < bytes.length; i++)
|
||||||
{
|
{
|
||||||
bytes[i] = fCache.bytes[offset + i];
|
bytes[i] = fCache.bytes[offset + i];
|
||||||
|
@ -961,10 +993,10 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryByte bytes[] = new MemoryByte[bytesRequested];
|
TraditionalMemoryByte bytes[] = new TraditionalMemoryByte[bytesRequested];
|
||||||
for(int i = 0; i < bytes.length; i++)
|
for(int i = 0; i < bytes.length; i++)
|
||||||
{
|
{
|
||||||
bytes[i] = new MemoryByte();
|
bytes[i] = new TraditionalMemoryByte();
|
||||||
bytes[i].setReadable(false);
|
bytes[i].setReadable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -983,13 +1015,13 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
return fEditBuffer.containsKey(address);
|
return fEditBuffer.containsKey(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MemoryByte[] getEditedMemory(BigInteger address)
|
private TraditionalMemoryByte[] getEditedMemory(BigInteger address)
|
||||||
{
|
{
|
||||||
assert Thread.currentThread().equals(
|
assert Thread.currentThread().equals(
|
||||||
Display.getDefault().getThread()) : TraditionalRenderingMessages
|
Display.getDefault().getThread()) : TraditionalRenderingMessages
|
||||||
.getString("TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$
|
.getString("TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$
|
||||||
|
|
||||||
return (MemoryByte[]) fEditBuffer.get(address);
|
return (TraditionalMemoryByte[]) fEditBuffer.get(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearEditBuffer()
|
public void clearEditBuffer()
|
||||||
|
@ -1014,7 +1046,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
while(iterator.hasNext())
|
while(iterator.hasNext())
|
||||||
{
|
{
|
||||||
BigInteger address = (BigInteger) iterator.next();
|
BigInteger address = (BigInteger) iterator.next();
|
||||||
MemoryByte[] bytes = (MemoryByte[]) fEditBuffer
|
TraditionalMemoryByte[] bytes = (TraditionalMemoryByte[]) fEditBuffer
|
||||||
.get(address);
|
.get(address);
|
||||||
|
|
||||||
byte byteValue[] = new byte[bytes.length];
|
byte byteValue[] = new byte[bytes.length];
|
||||||
|
@ -1038,7 +1070,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
clearEditBuffer();
|
clearEditBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEditedValue(BigInteger address, MemoryByte[] bytes)
|
public void setEditedValue(BigInteger address, TraditionalMemoryByte[] bytes)
|
||||||
{
|
{
|
||||||
assert Thread.currentThread().equals(
|
assert Thread.currentThread().equals(
|
||||||
Display.getDefault().getThread()) : TraditionalRenderingMessages
|
Display.getDefault().getThread()) : TraditionalRenderingMessages
|
||||||
|
|
|
@ -242,7 +242,7 @@ public class TextPane extends AbstractPane
|
||||||
* columns + col)
|
* columns + col)
|
||||||
* fRendering.getAddressesPerColumn()));
|
* fRendering.getAddressesPerColumn()));
|
||||||
|
|
||||||
MemoryByte bytes[] = fRendering.getBytes(cellAddress,
|
TraditionalMemoryByte bytes[] = fRendering.getBytes(cellAddress,
|
||||||
fRendering.getBytesPerColumn());
|
fRendering.getBytesPerColumn());
|
||||||
|
|
||||||
if(fRendering.getSelection().isSelected(cellAddress))
|
if(fRendering.getSelection().isSelected(cellAddress))
|
||||||
|
@ -281,31 +281,46 @@ public class TextPane extends AbstractPane
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void applyCustomColor(GC gc, MemoryByte bytes[], int col)
|
// Allow subclasses to override this method to do their own coloring
|
||||||
{
|
protected void applyCustomColor(GC gc, TraditionalMemoryByte bytes[], int col)
|
||||||
// TODO reuse, this could be in the abstract base
|
{
|
||||||
// TODO consider adding finer granularity?
|
// TODO consider adding finer granularity?
|
||||||
boolean anyByteChanged = false;
|
|
||||||
for(int n = 0; n < bytes.length && !anyByteChanged; n++)
|
|
||||||
if(bytes[n].isChanged())
|
|
||||||
anyByteChanged = true;
|
|
||||||
|
|
||||||
// TODO consider adding finer granularity?
|
|
||||||
boolean anyByteEditing = false;
|
boolean anyByteEditing = false;
|
||||||
for(int n = 0; n < bytes.length && !anyByteEditing; n++)
|
for(int n = 0; n < bytes.length && !anyByteEditing; n++)
|
||||||
if(bytes[n] instanceof TraditionalMemoryByte)
|
if(bytes[n] instanceof TraditionalMemoryByte)
|
||||||
if(((TraditionalMemoryByte) bytes[n]).isEdited())
|
if(((TraditionalMemoryByte) bytes[n]).isEdited())
|
||||||
anyByteEditing = true;
|
anyByteEditing = true;
|
||||||
|
|
||||||
if(anyByteEditing)
|
if(isOdd(col))
|
||||||
gc.setForeground(fRendering.getTraditionalRendering().getColorEdit());
|
gc.setForeground(fRendering.getTraditionalRendering().getColorText());
|
||||||
else if(anyByteChanged)
|
else
|
||||||
gc.setForeground(fRendering.getTraditionalRendering().getColorChanged());
|
gc.setForeground(fRendering.getTraditionalRendering().getColorTextAlternate());
|
||||||
else if(isOdd(col))
|
gc.setBackground(fRendering.getTraditionalRendering().getColorBackground());
|
||||||
gc.setForeground(fRendering.getTraditionalRendering().getColorText());
|
|
||||||
else
|
if(anyByteEditing)
|
||||||
gc.setForeground(fRendering.getTraditionalRendering().getColorTextAlternate());
|
{
|
||||||
|
gc.setForeground(fRendering.getTraditionalRendering().getColorEdit());
|
||||||
gc.setBackground(fRendering.getTraditionalRendering().getColorBackground());
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
boolean isColored = false;
|
||||||
|
for(int i = 0; i < fRendering.getHistoryDepth() && !isColored; i++)
|
||||||
|
{
|
||||||
|
// TODO consider adding finer granularity?
|
||||||
|
for(int n = 0; n < bytes.length; n++)
|
||||||
|
{
|
||||||
|
if(bytes[n].isChanged(i))
|
||||||
|
{
|
||||||
|
if(i == 0)
|
||||||
|
gc.setForeground(fRendering.getTraditionalRendering().getColorsChanged()[i]);
|
||||||
|
else
|
||||||
|
gc.setBackground(fRendering.getTraditionalRendering().getColorsChanged()[i]);
|
||||||
|
isColored = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -352,6 +352,7 @@ public class TraditionalRendering extends AbstractMemoryRendering implements IRe
|
||||||
|
|
||||||
private Color colorBackground;
|
private Color colorBackground;
|
||||||
private Color colorChanged;
|
private Color colorChanged;
|
||||||
|
private Color colorsChanged[] = null;
|
||||||
private Color colorEdit;
|
private Color colorEdit;
|
||||||
private Color colorSelection;
|
private Color colorSelection;
|
||||||
private Color colorText;
|
private Color colorText;
|
||||||
|
@ -417,12 +418,18 @@ public class TraditionalRendering extends AbstractMemoryRendering implements IRe
|
||||||
if(colorTextAlternate != null)
|
if(colorTextAlternate != null)
|
||||||
colorTextAlternate.dispose();
|
colorTextAlternate.dispose();
|
||||||
colorTextAlternate = null;
|
colorTextAlternate = null;
|
||||||
|
|
||||||
|
disposeChangedColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyPreferences()
|
public void applyPreferences()
|
||||||
{
|
{
|
||||||
if(!fRendering.isDisposed())
|
if(!fRendering.isDisposed())
|
||||||
{
|
{
|
||||||
|
IPreferenceStore store = TraditionalRenderingPlugin.getDefault().getPreferenceStore();
|
||||||
|
|
||||||
|
fRendering.setHistoryDepth(store.getInt(TraditionalRenderingPreferenceConstants.MEM_HISTORY_TRAILS_COUNT));
|
||||||
|
|
||||||
fRendering.setBackground(getColorBackground());
|
fRendering.setBackground(getColorBackground());
|
||||||
|
|
||||||
AbstractPane panes[] = fRendering.getRenderingPanes();
|
AbstractPane panes[] = fRendering.getRenderingPanes();
|
||||||
|
@ -448,6 +455,41 @@ public class TraditionalRendering extends AbstractMemoryRendering implements IRe
|
||||||
return colorChanged;
|
return colorChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void disposeChangedColors()
|
||||||
|
{
|
||||||
|
if(colorsChanged != null)
|
||||||
|
for(int i = 0; i < colorsChanged.length; i++)
|
||||||
|
colorsChanged[i].dispose();
|
||||||
|
colorsChanged = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color[] getColorsChanged()
|
||||||
|
{
|
||||||
|
if(colorsChanged != null && colorsChanged.length != fRendering.getHistoryDepth())
|
||||||
|
{
|
||||||
|
disposeChangedColors();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(colorsChanged == null)
|
||||||
|
{
|
||||||
|
colorsChanged = new Color[fRendering.getHistoryDepth()];
|
||||||
|
colorsChanged[0] = colorChanged;
|
||||||
|
int shades = fRendering.getHistoryDepth() + 4;
|
||||||
|
int red = (255 - colorChanged.getRed()) / shades;
|
||||||
|
int green = (255 - colorChanged.getGreen()) / shades;
|
||||||
|
int blue = (255 - colorChanged.getBlue()) / shades;
|
||||||
|
for(int i = 1; i < fRendering.getHistoryDepth(); i++)
|
||||||
|
{
|
||||||
|
colorsChanged[i] = new Color(colorChanged.getDevice(),
|
||||||
|
colorChanged.getRed() + ((shades - i) * red),
|
||||||
|
colorChanged.getGreen() + ((shades - i) * green),
|
||||||
|
colorChanged.getBlue() + ((shades - i) * blue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return colorsChanged;
|
||||||
|
}
|
||||||
|
|
||||||
public Color getColorEdit()
|
public Color getColorEdit()
|
||||||
{
|
{
|
||||||
return colorEdit;
|
return colorEdit;
|
||||||
|
@ -1060,6 +1102,7 @@ public class TraditionalRendering extends AbstractMemoryRendering implements IRe
|
||||||
{
|
{
|
||||||
if(this.fRendering != null)
|
if(this.fRendering != null)
|
||||||
this.fRendering.dispose();
|
this.fRendering.dispose();
|
||||||
|
disposeColors();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1126,11 +1169,23 @@ class TraditionalMemoryByte extends MemoryByte implements IMemoryByte
|
||||||
{
|
{
|
||||||
private boolean isEdited = false;
|
private boolean isEdited = false;
|
||||||
|
|
||||||
|
private boolean[] changeHistory = new boolean[0];
|
||||||
|
|
||||||
|
public TraditionalMemoryByte()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
public TraditionalMemoryByte(byte byteValue)
|
public TraditionalMemoryByte(byte byteValue)
|
||||||
{
|
{
|
||||||
super(byteValue);
|
super(byteValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TraditionalMemoryByte(byte byteValue, byte byteFlags)
|
||||||
|
{
|
||||||
|
super(byteValue, byteFlags);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEdited()
|
public boolean isEdited()
|
||||||
{
|
{
|
||||||
return isEdited;
|
return isEdited;
|
||||||
|
@ -1140,6 +1195,26 @@ class TraditionalMemoryByte extends MemoryByte implements IMemoryByte
|
||||||
{
|
{
|
||||||
isEdited = edited;
|
isEdited = edited;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isChanged(int historyDepth)
|
||||||
|
{
|
||||||
|
return changeHistory.length > historyDepth && changeHistory[historyDepth];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChanged(int historyDepth, boolean changed)
|
||||||
|
{
|
||||||
|
if(historyDepth >= changeHistory.length)
|
||||||
|
{
|
||||||
|
boolean newChangeHistory[] = new boolean[historyDepth + 1];
|
||||||
|
System.arraycopy(changeHistory, 0, newChangeHistory, 0, changeHistory.length);
|
||||||
|
changeHistory = newChangeHistory;
|
||||||
|
}
|
||||||
|
|
||||||
|
changeHistory[historyDepth] = changed;
|
||||||
|
|
||||||
|
if(historyDepth == 0)
|
||||||
|
this.setChanged(changed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CopyAction extends Action
|
class CopyAction extends Action
|
||||||
|
|
|
@ -40,4 +40,6 @@ public class TraditionalRenderingPreferenceConstants {
|
||||||
|
|
||||||
public static final String MEM_EDIT_BUFFER_SAVE_ON_ENTER_OR_FOCUS_LOST = "saveOnEnterOrFocusLost";
|
public static final String MEM_EDIT_BUFFER_SAVE_ON_ENTER_OR_FOCUS_LOST = "saveOnEnterOrFocusLost";
|
||||||
|
|
||||||
|
public static final String MEM_HISTORY_TRAILS_COUNT = "memoryHistoryTrailsCount";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,8 @@ public class TraditionalRenderingPreferenceInitializer extends AbstractPreferenc
|
||||||
|
|
||||||
store.setDefault(TraditionalRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE,
|
store.setDefault(TraditionalRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE,
|
||||||
TraditionalRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE_ON_ENTER_ONLY);
|
TraditionalRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE_ON_ENTER_ONLY);
|
||||||
|
|
||||||
|
store.setDefault(TraditionalRenderingPreferenceConstants.MEM_HISTORY_TRAILS_COUNT, "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,9 @@ public class TraditionalRenderingPreferencePage
|
||||||
addField(new RadioGroupFieldEditor(TraditionalRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE,
|
addField(new RadioGroupFieldEditor(TraditionalRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE,
|
||||||
"Edit Buffer", 1, new String[][] { { "Save on E&nter, Cancel on Focus Lost", "saveOnEnterCancelOnFocusLost" },
|
"Edit Buffer", 1, new String[][] { { "Save on E&nter, Cancel on Focus Lost", "saveOnEnterCancelOnFocusLost" },
|
||||||
{ "Save on Enter or Focus L&ost", "saveOnEnterOrFocusLost" } }, getFieldEditorParent()));
|
{ "Save on Enter or Focus L&ost", "saveOnEnterOrFocusLost" } }, getFieldEditorParent()));
|
||||||
|
|
||||||
|
addField(new ScaleFieldEditor(TraditionalRenderingPreferenceConstants.MEM_HISTORY_TRAILS_COUNT,
|
||||||
|
"History &Trail Levels", getFieldEditorParent(), 1, 10, 1, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|
Loading…
Add table
Reference in a new issue