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.model.MemoryByte;
|
||||
import org.eclipse.swt.events.PaintEvent;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
|
||||
|
@ -102,8 +103,8 @@ public class DataPane extends AbstractPane
|
|||
}
|
||||
//else
|
||||
{
|
||||
if(bytes[i] instanceof TraditionalMemoryByte)
|
||||
bytesToSet[i].setEdited(((TraditionalMemoryByte) bytes[i]).isEdited());
|
||||
// if(bytes[i] instanceof TraditionalMemoryByte)
|
||||
// bytesToSet[i].setEdited(((TraditionalMemoryByte) bytes[i]).isEdited());
|
||||
bytesToSet[i].setChanged(bytes[i].isChanged());
|
||||
}
|
||||
}
|
||||
|
@ -272,7 +273,7 @@ public class DataPane extends AbstractPane
|
|||
* fRendering.getColumnCount() + col)
|
||||
* fRendering.getAddressesPerColumn()));
|
||||
|
||||
MemoryByte bytes[] = fRendering.getBytes(cellAddress,
|
||||
TraditionalMemoryByte bytes[] = fRendering.getBytes(cellAddress,
|
||||
fRendering.getBytesPerColumn());
|
||||
|
||||
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
|
||||
applyCustomColor(gc, bytes, 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
|
||||
protected void applyCustomColor(GC gc, MemoryByte bytes[], int col)
|
||||
protected void applyCustomColor(GC gc, TraditionalMemoryByte bytes[], int col)
|
||||
{
|
||||
// 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;
|
||||
for(int n = 0; n < bytes.length && !anyByteEditing; n++)
|
||||
if(bytes[n] instanceof TraditionalMemoryByte)
|
||||
if(((TraditionalMemoryByte) bytes[n]).isEdited())
|
||||
anyByteEditing = true;
|
||||
|
||||
// TODO consider adding finer granularity?
|
||||
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))
|
||||
if(isOdd(col))
|
||||
gc.setForeground(fRendering.getTraditionalRendering().getColorText());
|
||||
else
|
||||
gc.setForeground(fRendering.getTraditionalRendering().getColorTextAlternate());
|
||||
|
||||
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 refresh();
|
||||
public MemoryByte[] getBytes(BigInteger address, int bytesRequested) throws DebugException;
|
||||
public TraditionalMemoryByte[] getBytes(BigInteger address, int bytesRequested) throws DebugException;
|
||||
public void archiveDeltas();
|
||||
public void setEditedValue(BigInteger address, MemoryByte[] bytes);
|
||||
public void setEditedValue(BigInteger address, TraditionalMemoryByte[] bytes);
|
||||
public void clearEditBuffer();
|
||||
public void writeEditBuffer();
|
||||
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.renderings.GoToAddressComposite;
|
||||
import org.eclipse.jface.dialogs.IDialogConstants;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.resource.JFaceResources;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.dnd.Clipboard;
|
||||
|
@ -106,7 +107,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
private boolean fIsTargetLittleEndian = false;
|
||||
|
||||
private boolean fIsDisplayLittleEndian = false;
|
||||
|
||||
|
||||
// constants used to identify radix
|
||||
public final static int RADIX_HEX = 1;
|
||||
|
||||
|
@ -482,6 +483,16 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
{
|
||||
return fSelection;
|
||||
}
|
||||
|
||||
protected int getHistoryDepth()
|
||||
{
|
||||
return fViewportCache.getHistoryDepth();
|
||||
}
|
||||
|
||||
protected void setHistoryDepth(int depth)
|
||||
{
|
||||
fViewportCache.setHistoryDepth(depth);
|
||||
}
|
||||
|
||||
public void logError(String message, Exception e)
|
||||
{
|
||||
|
@ -609,7 +620,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
return fViewportCache;
|
||||
}
|
||||
|
||||
public MemoryByte[] getBytes(BigInteger address, int bytes)
|
||||
public TraditionalMemoryByte[] getBytes(BigInteger address, int bytes)
|
||||
throws DebugException
|
||||
{
|
||||
return getViewportCache().getBytes(address, bytes);
|
||||
|
@ -652,7 +663,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -662,7 +673,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
|
||||
BigInteger end;
|
||||
|
||||
MemoryByte[] bytes;
|
||||
TraditionalMemoryByte[] bytes;
|
||||
|
||||
public MemoryUnit clone()
|
||||
{
|
||||
|
@ -670,9 +681,9 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
|
||||
b.start = this.start;
|
||||
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++)
|
||||
b.bytes[i] = new MemoryByte(this.bytes[i].getValue());
|
||||
b.bytes[i] = new TraditionalMemoryByte(this.bytes[i].getValue());
|
||||
|
||||
return b;
|
||||
}
|
||||
|
@ -694,8 +705,10 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
|
||||
protected MemoryUnit fCache = null;
|
||||
|
||||
protected MemoryUnit fHistoryCache = null;
|
||||
protected MemoryUnit fHistoryCache[] = new MemoryUnit[0];
|
||||
|
||||
protected int fHistoryDepth = 0;
|
||||
|
||||
public ViewportCache()
|
||||
{
|
||||
start();
|
||||
|
@ -709,6 +722,17 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
this.notify();
|
||||
}
|
||||
}
|
||||
|
||||
public int getHistoryDepth()
|
||||
{
|
||||
return fHistoryDepth;
|
||||
}
|
||||
|
||||
public void setHistoryDepth(int depth)
|
||||
{
|
||||
fHistoryDepth = depth;
|
||||
fHistoryCache = new MemoryUnit[fHistoryDepth];
|
||||
}
|
||||
|
||||
public void refresh()
|
||||
{
|
||||
|
@ -737,8 +761,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
private void queueRequest(BigInteger startAddress, BigInteger endAddress)
|
||||
{
|
||||
AddressPair pair = new AddressPair(startAddress, endAddress);
|
||||
if(!pair.equals(fLastQueued))
|
||||
queue(pair);
|
||||
queue(pair);
|
||||
}
|
||||
|
||||
private void queueRequestArchiveDeltas()
|
||||
|
@ -751,8 +774,11 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
{
|
||||
synchronized(fQueue)
|
||||
{
|
||||
fQueue.addElement(element);
|
||||
fLastQueued = element;
|
||||
if(!(fQueue.size() > 0 && element.equals(fLastQueued)))
|
||||
{
|
||||
fQueue.addElement(element);
|
||||
fLastQueued = element;
|
||||
}
|
||||
}
|
||||
synchronized(this)
|
||||
{
|
||||
|
@ -789,7 +815,10 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
}
|
||||
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)
|
||||
{
|
||||
|
@ -837,9 +866,9 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
final MemoryByte readBytes[] = memoryBlock
|
||||
.getBytesFromAddress(startAddress, units);
|
||||
|
||||
MemoryByte cachedBytes[] = new MemoryByte[readBytes.length];
|
||||
TraditionalMemoryByte cachedBytes[] = new TraditionalMemoryByte[readBytes.length];
|
||||
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.
|
||||
if (cachedBytes.length > 0) {
|
||||
|
@ -855,7 +884,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
if(addressableSize.compareTo(BigInteger.ONE) != 0)
|
||||
{
|
||||
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 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()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
// generate deltas
|
||||
if(fHistoryCache != null && fHistoryCache.isValid())
|
||||
{
|
||||
BigInteger maxStart = startAddress
|
||||
.max(fHistoryCache.start);
|
||||
BigInteger minEnd = endAddress
|
||||
.min(fHistoryCache.end).subtract(
|
||||
BigInteger.valueOf(1));
|
||||
|
||||
BigInteger overlapLength = minEnd
|
||||
.subtract(maxStart);
|
||||
if(overlapLength.compareTo(BigInteger.valueOf(0)) > 0)
|
||||
{
|
||||
// there is overlap
|
||||
|
||||
int offsetIntoOld = maxStart.subtract(
|
||||
fHistoryCache.start).intValue();
|
||||
int offsetIntoNew = maxStart.subtract(
|
||||
startAddress).intValue();
|
||||
|
||||
for(int i = overlapLength.intValue(); i >= 0; i--)
|
||||
{
|
||||
cachedBytesFinal[offsetIntoNew + i]
|
||||
.setChanged(cachedBytesFinal[offsetIntoNew
|
||||
+ i].getValue() != fHistoryCache.bytes[offsetIntoOld
|
||||
+ i].getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int historyIndex = 0; historyIndex < getHistoryDepth(); historyIndex++)
|
||||
{
|
||||
if(fHistoryCache[historyIndex] != null && fHistoryCache[historyIndex].isValid())
|
||||
{
|
||||
BigInteger maxStart = startAddress
|
||||
.max(fHistoryCache[historyIndex].start);
|
||||
BigInteger minEnd = endAddress
|
||||
.min(fHistoryCache[historyIndex].end).subtract(
|
||||
BigInteger.valueOf(1));
|
||||
|
||||
BigInteger overlapLength = minEnd
|
||||
.subtract(maxStart);
|
||||
if(overlapLength.compareTo(BigInteger.valueOf(0)) > 0)
|
||||
{
|
||||
// there is overlap
|
||||
|
||||
int offsetIntoOld = maxStart.subtract(
|
||||
fHistoryCache[historyIndex].start).intValue();
|
||||
int offsetIntoNew = maxStart.subtract(
|
||||
startAddress).intValue();
|
||||
|
||||
for(int i = overlapLength.intValue(); i >= 0; i--)
|
||||
{
|
||||
cachedBytesFinal[offsetIntoNew + i]
|
||||
.setChanged(historyIndex, cachedBytesFinal[offsetIntoNew
|
||||
+ i].getValue() != fHistoryCache[historyIndex].bytes[offsetIntoOld
|
||||
+ i].getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fCache = new MemoryUnit();
|
||||
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
|
||||
// use case of 1) connect to target; 2) edit memory before the first suspend debug event; 3) paint
|
||||
// differences in changed color.
|
||||
if(fHistoryCache == null)
|
||||
fHistoryCache = fCache.clone();
|
||||
if(fHistoryCache[0] == null)
|
||||
fHistoryCache[0] = fCache.clone();
|
||||
|
||||
Rendering.this.redrawPanes();
|
||||
}
|
||||
|
@ -927,7 +959,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
}
|
||||
|
||||
// bytes will be fetched from cache
|
||||
public MemoryByte[] getBytes(BigInteger address, int bytesRequested)
|
||||
public TraditionalMemoryByte[] getBytes(BigInteger address, int bytesRequested)
|
||||
throws DebugException
|
||||
{
|
||||
assert Thread.currentThread().equals(
|
||||
|
@ -952,7 +984,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
if(contains)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
bytes[i] = fCache.bytes[offset + i];
|
||||
|
@ -961,10 +993,10 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
return bytes;
|
||||
}
|
||||
|
||||
MemoryByte bytes[] = new MemoryByte[bytesRequested];
|
||||
TraditionalMemoryByte bytes[] = new TraditionalMemoryByte[bytesRequested];
|
||||
for(int i = 0; i < bytes.length; i++)
|
||||
{
|
||||
bytes[i] = new MemoryByte();
|
||||
bytes[i] = new TraditionalMemoryByte();
|
||||
bytes[i].setReadable(false);
|
||||
}
|
||||
|
||||
|
@ -983,13 +1015,13 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
return fEditBuffer.containsKey(address);
|
||||
}
|
||||
|
||||
private MemoryByte[] getEditedMemory(BigInteger address)
|
||||
private TraditionalMemoryByte[] getEditedMemory(BigInteger address)
|
||||
{
|
||||
assert Thread.currentThread().equals(
|
||||
Display.getDefault().getThread()) : TraditionalRenderingMessages
|
||||
.getString("TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$
|
||||
|
||||
return (MemoryByte[]) fEditBuffer.get(address);
|
||||
return (TraditionalMemoryByte[]) fEditBuffer.get(address);
|
||||
}
|
||||
|
||||
public void clearEditBuffer()
|
||||
|
@ -1014,7 +1046,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
while(iterator.hasNext())
|
||||
{
|
||||
BigInteger address = (BigInteger) iterator.next();
|
||||
MemoryByte[] bytes = (MemoryByte[]) fEditBuffer
|
||||
TraditionalMemoryByte[] bytes = (TraditionalMemoryByte[]) fEditBuffer
|
||||
.get(address);
|
||||
|
||||
byte byteValue[] = new byte[bytes.length];
|
||||
|
@ -1038,7 +1070,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
clearEditBuffer();
|
||||
}
|
||||
|
||||
public void setEditedValue(BigInteger address, MemoryByte[] bytes)
|
||||
public void setEditedValue(BigInteger address, TraditionalMemoryByte[] bytes)
|
||||
{
|
||||
assert Thread.currentThread().equals(
|
||||
Display.getDefault().getThread()) : TraditionalRenderingMessages
|
||||
|
|
|
@ -242,7 +242,7 @@ public class TextPane extends AbstractPane
|
|||
* columns + col)
|
||||
* fRendering.getAddressesPerColumn()));
|
||||
|
||||
MemoryByte bytes[] = fRendering.getBytes(cellAddress,
|
||||
TraditionalMemoryByte bytes[] = fRendering.getBytes(cellAddress,
|
||||
fRendering.getBytesPerColumn());
|
||||
|
||||
if(fRendering.getSelection().isSelected(cellAddress))
|
||||
|
@ -281,31 +281,46 @@ public class TextPane extends AbstractPane
|
|||
|
||||
}
|
||||
|
||||
protected void applyCustomColor(GC gc, MemoryByte bytes[], int col)
|
||||
{
|
||||
// TODO reuse, this could be in the abstract base
|
||||
// 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?
|
||||
// Allow subclasses to override this method to do their own coloring
|
||||
protected void applyCustomColor(GC gc, TraditionalMemoryByte bytes[], int col)
|
||||
{
|
||||
// TODO consider adding finer granularity?
|
||||
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());
|
||||
else
|
||||
gc.setForeground(fRendering.getTraditionalRendering().getColorTextAlternate());
|
||||
|
||||
gc.setBackground(fRendering.getTraditionalRendering().getColorBackground());
|
||||
}
|
||||
if(((TraditionalMemoryByte) bytes[n]).isEdited())
|
||||
anyByteEditing = true;
|
||||
|
||||
if(isOdd(col))
|
||||
gc.setForeground(fRendering.getTraditionalRendering().getColorText());
|
||||
else
|
||||
gc.setForeground(fRendering.getTraditionalRendering().getColorTextAlternate());
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -352,6 +352,7 @@ public class TraditionalRendering extends AbstractMemoryRendering implements IRe
|
|||
|
||||
private Color colorBackground;
|
||||
private Color colorChanged;
|
||||
private Color colorsChanged[] = null;
|
||||
private Color colorEdit;
|
||||
private Color colorSelection;
|
||||
private Color colorText;
|
||||
|
@ -417,12 +418,18 @@ public class TraditionalRendering extends AbstractMemoryRendering implements IRe
|
|||
if(colorTextAlternate != null)
|
||||
colorTextAlternate.dispose();
|
||||
colorTextAlternate = null;
|
||||
|
||||
disposeChangedColors();
|
||||
}
|
||||
|
||||
public void applyPreferences()
|
||||
{
|
||||
if(!fRendering.isDisposed())
|
||||
{
|
||||
IPreferenceStore store = TraditionalRenderingPlugin.getDefault().getPreferenceStore();
|
||||
|
||||
fRendering.setHistoryDepth(store.getInt(TraditionalRenderingPreferenceConstants.MEM_HISTORY_TRAILS_COUNT));
|
||||
|
||||
fRendering.setBackground(getColorBackground());
|
||||
|
||||
AbstractPane panes[] = fRendering.getRenderingPanes();
|
||||
|
@ -448,6 +455,41 @@ public class TraditionalRendering extends AbstractMemoryRendering implements IRe
|
|||
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()
|
||||
{
|
||||
return colorEdit;
|
||||
|
@ -1060,6 +1102,7 @@ public class TraditionalRendering extends AbstractMemoryRendering implements IRe
|
|||
{
|
||||
if(this.fRendering != null)
|
||||
this.fRendering.dispose();
|
||||
disposeColors();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
@ -1126,11 +1169,23 @@ class TraditionalMemoryByte extends MemoryByte implements IMemoryByte
|
|||
{
|
||||
private boolean isEdited = false;
|
||||
|
||||
private boolean[] changeHistory = new boolean[0];
|
||||
|
||||
public TraditionalMemoryByte()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public TraditionalMemoryByte(byte byteValue)
|
||||
{
|
||||
super(byteValue);
|
||||
}
|
||||
|
||||
public TraditionalMemoryByte(byte byteValue, byte byteFlags)
|
||||
{
|
||||
super(byteValue, byteFlags);
|
||||
}
|
||||
|
||||
public boolean isEdited()
|
||||
{
|
||||
return isEdited;
|
||||
|
@ -1140,6 +1195,26 @@ class TraditionalMemoryByte extends MemoryByte implements IMemoryByte
|
|||
{
|
||||
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
|
||||
|
|
|
@ -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_HISTORY_TRAILS_COUNT = "memoryHistoryTrailsCount";
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,8 @@ public class TraditionalRenderingPreferenceInitializer extends AbstractPreferenc
|
|||
|
||||
store.setDefault(TraditionalRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE,
|
||||
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,
|
||||
"Edit Buffer", 1, new String[][] { { "Save on E&nter, Cancel on Focus Lost", "saveOnEnterCancelOnFocusLost" },
|
||||
{ "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)
|
||||
|
|
Loading…
Add table
Reference in a new issue