1
0
Fork 0
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:
Ted Williams 2008-05-21 05:11:09 +00:00
parent 237bb02706
commit c289fa0b9b
8 changed files with 248 additions and 104 deletions

View file

@ -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;
}
}
}
}
} }
} }

View file

@ -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);

View file

@ -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

View file

@ -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;
}
}
}
}
}
} }

View file

@ -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

View file

@ -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";
} }

View file

@ -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");
} }
} }

View file

@ -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)