diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/.options b/memory/org.eclipse.cdt.debug.ui.memory.traditional/.options new file mode 100644 index 00000000000..5a38e315d1d --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/.options @@ -0,0 +1 @@ +org.eclipse.cdt.debug.ui.memory.traditional/debug = false diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/META-INF/MANIFEST.MF b/memory/org.eclipse.cdt.debug.ui.memory.traditional/META-INF/MANIFEST.MF index 006d49c9b94..9ac9aee28f3 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.traditional/META-INF/MANIFEST.MF +++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.debug.ui.memory.traditional;singleton:=true -Bundle-Version: 1.2.1.qualifier +Bundle-Version: 1.3.0.qualifier Bundle-Localization: plugin Require-Bundle: org.eclipse.debug.core, org.eclipse.debug.ui, diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/plugin.xml b/memory/org.eclipse.cdt.debug.ui.memory.traditional/plugin.xml index 8eb9084eb2c..a71decad82f 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.traditional/plugin.xml +++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/plugin.xml @@ -44,6 +44,19 @@ + + + + + + + + diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/pom.xml b/memory/org.eclipse.cdt.debug.ui.memory.traditional/pom.xml index 142ae8131a5..a6338d819aa 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.traditional/pom.xml +++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/pom.xml @@ -11,7 +11,7 @@ ../../pom.xml - 1.2.1-SNAPSHOT + 1.3.0-SNAPSHOT org.eclipse.cdt.debug.ui.memory.traditional eclipse-plugin diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/AbstractPane.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/AbstractPane.java index c99a7d0be4d..fbb321fa644 100755 --- a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/AbstractPane.java +++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/AbstractPane.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2015 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Teodor Madan (Freescale) - Fix PageDn/PageUp *******************************************************************************/ package org.eclipse.cdt.debug.ui.memory.traditional; @@ -211,6 +212,22 @@ public abstract class AbstractPane extends Canvas { handlePageUpKey(); } + else if(ke.keyCode == SWT.HOME && (ke.stateMask & SWT.CTRL) != 0) + { + fRendering.gotoAddress(fRendering.getMemoryBlockStartAddress()); + } + else if(ke.keyCode == SWT.END && (ke.stateMask & SWT.CTRL) != 0) + { + fRendering.gotoAddress(fRendering.getMemoryBlockEndAddress()); + } + else if(ke.keyCode == SWT.HOME && (ke.stateMask & SWT.CTRL) == 0) + { + handleHomeKey(); + } + else if(ke.keyCode == SWT.END && (ke.stateMask & SWT.CTRL) == 0) + { + handleEndKey(); + } else if(ke.keyCode == SWT.ESC) { fRendering.getViewportCache().clearEditBuffer(); @@ -311,7 +328,7 @@ public abstract class AbstractPane extends Canvas this.addFocusListener(createFocusListener()); } - protected MouseListener createMouseListener(){ + protected MouseListener createMouseListener(){ return new AbstractPaneMouseListener(); } @@ -422,7 +439,35 @@ public abstract class AbstractPane extends Canvas updateCaret(); ensureCaretWithinViewport(); } - + + /** + * @since 1.3 + */ + protected void handleEndKey() { + // calculate offset from the end of the row + BigInteger lastCellAddress = fRendering.getViewportEndAddress().subtract(BigInteger.ONE); + + int cellOffset = fCaretAddress.subtract(lastCellAddress).intValue(); + int row = cellOffset / fRendering.getAddressableCellsPerRow(); + setCaretAddress(lastCellAddress.add(BigInteger.valueOf(row * fRendering.getAddressableCellsPerRow()))); + + updateCaret(); + ensureCaretWithinViewport(); + } + + /** + * @since 1.3 + */ + protected void handleHomeKey() { + // calculate offset from the beginning of the row + int cellOffset = fCaretAddress.subtract(fRendering.getViewportStartAddress()).intValue(); + int row = cellOffset / fRendering.getAddressableCellsPerRow(); + setCaretAddress(fRendering.getViewportStartAddress().add(BigInteger.valueOf(row * fRendering.getAddressableCellsPerRow()))); + + updateCaret(); + ensureCaretWithinViewport(); + } + protected void handleMouseDoubleClick(MouseEvent me) { try @@ -586,10 +631,16 @@ public abstract class AbstractPane extends Canvas { // The caret was moved outside the viewport bounds: Scroll the // viewport up or down by a row, depending on where the caret is - + boolean upArrow = fCaretAddress.compareTo(vpStart) <= 0; + int rows = (upArrow ? -1 : 1 ); + if (upArrow) { + rows -= vpStart.subtract(fCaretAddress).intValue()/fRendering.getAddressableCellsPerRow(); + } else { + rows += fCaretAddress.subtract(vpEnd).intValue()/fRendering.getAddressableCellsPerRow(); + } ScrollBar vBar = fRendering.getVerticalBar(); - vBar.setSelection(vBar.getSelection() + (upArrow ? -1 : 1)); + vBar.setSelection(vBar.getSelection() + rows); vBar.notifyListeners(SWT.Selection, new Event()); // Check to see if we're at the beginning or end of a line, and diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/Rendering.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/Rendering.java index fc5e7cfa651..da868d29511 100755 --- a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/Rendering.java +++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/Rendering.java @@ -9,13 +9,13 @@ * Ted R Williams (Wind River Systems, Inc.) - initial implementation * Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730) * Ling Wang (Silicon Laboratories) - Honor start address (Bug 414519) + * Teodor Madan (Freescale) - Fix scrolling for memory spaces with 64-bit address *******************************************************************************/ package org.eclipse.cdt.debug.ui.memory.traditional; -import java.math.BigDecimal; import java.math.BigInteger; -import java.math.MathContext; +import java.text.MessageFormat; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; @@ -131,14 +131,6 @@ public class Rendering extends Composite implements IDebugEventSetListener public final static int PANE_TEXT = 3; - /** - * Decimal precision used when converting between scroll units and number of - * memory rows. Calculations do not need to be exact; two decimal places is - * good enough. - */ - static private final MathContext SCROLL_CONVERSION_PRECISION = new MathContext(2); - - // constants used to identify text, maybe java should be queried for all available sets public final static int TEXT_ISO_8859_1 = 1; public final static int TEXT_USASCII = 2; @@ -426,32 +418,14 @@ public class Rendering extends Composite implements IDebugEventSetListener case SWT.SCROLL_LINE: // See: BUG 203068 selection event details broken on GTK < 2.6 default: - if(getVerticalBar().getSelection() == getVerticalBar().getMinimum()) - { - // Set view port start address to the start address of the Memory Block - fViewportAddress = Rendering.this.getMemoryBlockStartAddress(); - } - else if(getVerticalBar().getSelection() == getVerticalBar().getMaximum()) - { - // The view port end address should be less or equal to the the end address of the Memory Block - // Set view port address to be bigger than the end address of the Memory Block for now - // and let ensureViewportAddressDisplayable() to figure out the correct view port start address - fViewportAddress = Rendering.this.getMemoryBlockEndAddress(); - } - else - { - // Figure out the delta, ignore events with no delta - int deltaScroll = getVerticalBar().getSelection() - fCurrentScrollSelection; - if (deltaScroll == 0) - break; - - BigInteger deltaRows = scrollbar2rows(deltaScroll); - - BigInteger newAddress = fViewportAddress.add(BigInteger.valueOf( - getAddressableCellsPerRow()).multiply(deltaRows)); - - fViewportAddress = newAddress; - } + // Figure out the delta, ignore events with no delta + int deltaScroll = getVerticalBar().getSelection() - fCurrentScrollSelection; + if (deltaScroll == 0) + break; + + fViewportAddress = fViewportAddress.add(BigInteger.valueOf( + getAddressableCellsPerRow()).multiply(BigInteger.valueOf(deltaScroll))); + ensureViewportAddressDisplayable(); // Update tooltip // FIXME conversion from slider to scrollbar @@ -709,7 +683,9 @@ public class Rendering extends Composite implements IDebugEventSetListener } // default visibility for performance - ViewportCache fViewportCache = new ViewportCache(); + ViewportCache fViewportCache = new ViewportCache(); + + private BigInteger fScrollStartAddress = BigInteger.ZERO; private interface Request { @@ -1461,7 +1437,7 @@ public class Rendering extends Composite implements IDebugEventSetListener getVerticalBar().setMinimum(1); // scrollbar maximum range is Integer.MAX_VALUE. - getVerticalBar().setMaximum(getMaxScrollRange().min(BigInteger.valueOf(Integer.MAX_VALUE)).intValue()); + getVerticalBar().setMaximum(getMaxScrollLines()); getVerticalBar().setIncrement(1); getVerticalBar().setPageIncrement(this.getRowCount() -1); //TW FIXME conversion of slider to scrollbar @@ -1528,7 +1504,8 @@ public class Rendering extends Composite implements IDebugEventSetListener // reset the caret and selection state (no caret and no selection) fCaretAddress = null; fSelection = new Selection(); - + + ensureViewportAddressDisplayable(); redrawPanes(); } @@ -1547,6 +1524,30 @@ public class Rendering extends Composite implements IDebugEventSetListener return fViewportAddress.add(BigInteger.valueOf(this.getBytesPerRow() * getRowCount() / getAddressableSize())); } + private BigInteger getScrollStartAddress() + { + return fScrollStartAddress; + } + + private void setScrollStartAddress(BigInteger newAddress) + { + fScrollStartAddress = newAddress; + } + + private BigInteger getScrollEndAddress() + { + int scrollLines = getMaxScrollLines(); + // substract scroll thumb as it is not possible to scroll beyond it + scrollLines -= getVerticalBar().getThumb(); + + BigInteger newAddress = getScrollStartAddress().add( + BigInteger.valueOf(getAddressableCellsPerRow()).multiply( + BigInteger.valueOf(scrollLines)) + ); + + return newAddress.min(getMemoryBlockEndAddress()); + } + public String getAddressString(BigInteger address) { StringBuffer addressString = new StringBuffer(address.toString(16) @@ -1647,77 +1648,83 @@ public class Rendering extends Composite implements IDebugEventSetListener } /** - * @return Set current scroll selection + * Update current scroll selection to match current viewport range */ protected void setCurrentScrollSelection() { - BigInteger selection = getViewportStartAddress().divide( - BigInteger.valueOf(getAddressableCellsPerRow())); - - fCurrentScrollSelection = rows2scrollbar(selection); + BigInteger viewportStartAddress = getViewportStartAddress(); + if (TraceOptions.DEBUG) { + TraceOptions.trace(MessageFormat.format( + "Update scroll for viewrange[0x{0} : 0x{1}]:\n", + viewportStartAddress.toString(16), getViewportEndAddress().toString(16))); + TraceOptions.trace(MessageFormat.format( + " current ScrollRange=[0x{0} : 0x{1}]; selection = {2}\n", + getScrollStartAddress().toString(16), getScrollEndAddress().toString(16), + fCurrentScrollSelection)); + } + BigInteger addressableRow = BigInteger.valueOf(getAddressableCellsPerRow()); + if ((viewportStartAddress.compareTo(getScrollStartAddress()) <= 0)) { + // must reposition scroll area, center position into the center of the new scroll area + // unless it is already at the start of first line. + + int scrollLines = getMaxScrollLines()/2; + BigInteger newScrollStart = BigInteger.ZERO.max(viewportStartAddress.subtract( + BigInteger.valueOf(scrollLines).multiply(addressableRow)) + ); + setScrollStartAddress(newScrollStart); + + if (TraceOptions.DEBUG) { + TraceOptions.trace(MessageFormat.format( + " new ScrollRange=[0x{0} : 0x{1}]\n", + getScrollStartAddress().toString(16), getScrollEndAddress().toString(16))); + } + } else if (getViewportEndAddress().compareTo(getScrollEndAddress()) >= 0) { + // must reposition scroll area, center position into the center of the new scroll area + // unless when user gets closer to end of addressable size of memory, when leave + // scroll start address at end of block memory scroll start + + BigInteger eomScrollStart = getMemoryBlockEndAddress().add(BigInteger.ONE). + subtract( BigInteger.valueOf(getMaxScrollLines() - getVerticalBar().getThumb()).multiply(addressableRow)); + + int scrollLines = getMaxScrollLines()/2; + BigInteger newScrollStart = eomScrollStart.min(viewportStartAddress.subtract( + BigInteger.valueOf(scrollLines).multiply(addressableRow)) + ); + setScrollStartAddress(newScrollStart); + + if (TraceOptions.DEBUG) { + TraceOptions.trace(MessageFormat.format( + " new ScrollRange=[0x{0} : 0x{1}]\n", + getScrollStartAddress().toString(16), getScrollEndAddress().toString(16))); + } + } + + // calculate selection line from the start of scroll area + fCurrentScrollSelection = viewportStartAddress.subtract(getScrollStartAddress()).divide( + addressableRow).intValue() + 1; + if (TraceOptions.DEBUG) { + TraceOptions.trace(MessageFormat.format(" new selection={0}\n", fCurrentScrollSelection)); + } getVerticalBar().setSelection(fCurrentScrollSelection); } - + /** * compute the maximum scrolling range. * @return number of lines that rendering can display */ - private BigInteger getMaxScrollRange() { + private int getMaxScrollLines() { BigInteger difference = getMemoryBlockEndAddress().subtract(getMemoryBlockStartAddress()).add(BigInteger.ONE); BigInteger maxScrollRange = difference.divide(BigInteger.valueOf(getAddressableCellsPerRow())); if(maxScrollRange.multiply(BigInteger.valueOf(getAddressableCellsPerRow())).compareTo(difference) != 0) - maxScrollRange = maxScrollRange.add(BigInteger.ONE); - + maxScrollRange = maxScrollRange.add(BigInteger.ONE); // add a line to hold bytes that do not fill an entire raw + // support targets with an addressable size greater than 1 maxScrollRange = maxScrollRange.divide(BigInteger.valueOf(getAddressableSize())); - return maxScrollRange; + + // cap to maximum lines a SWT ScrollBar can hold. + return maxScrollRange.min(BigInteger.valueOf(Integer.MAX_VALUE)).intValue(); } - /** - * The scroll range is limited by SWT. Because it can be less than the - * number of rows (of memory) that we need to display, we need an arithmetic - * mapping. - * - * @return ratio this function returns how many rows a scroll bar unit - * represents. The number will be some fractional value, up to but - * not exceeding the value 1. I.e., when the scroll range exceeds - * the row range, we use a 1:1 mapping. - */ - private final BigDecimal getScrollRatio() { - BigInteger maxRange = getMaxScrollRange(); - if (maxRange.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0 ) { - return new BigDecimal(maxRange).divide(BigDecimal.valueOf(Integer.MAX_VALUE), SCROLL_CONVERSION_PRECISION); - } else { - return BigDecimal.ONE; - } - } - - /** - * Convert memory row units to scroll bar units. The scroll range is limited - * by SWT. Because it can be less than the number of rows (of memory) that - * we need to display, we need an arithmetic mapping. - - * @param rows - * units of memory - * @return scrollbar units - */ - private int rows2scrollbar(BigInteger rows) { - return new BigDecimal(rows).divide(getScrollRatio(), SCROLL_CONVERSION_PRECISION).intValue(); - } - - /** - * Convert scroll bar units to memory row units. The scroll range is limited - * by SWT. Because it can be less than the number of rows (of memory) that - * we need to display, we need an arithmetic mapping. - * - * @param scrollbarUnits - * scrollbar units - * @return number of rows of memory - */ - private BigInteger scrollbar2rows(int scrollbarUnits) { - return getScrollRatio().multiply(BigDecimal.valueOf(scrollbarUnits), SCROLL_CONVERSION_PRECISION).toBigInteger(); - } - /** * @return start address of the memory block */ diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraceOptions.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraceOptions.java new file mode 100644 index 00000000000..2b055c0e87a --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraceOptions.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2015 Freescale, and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Teodor Madan (Freescale) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.memory.traditional; + + +import java.util.Hashtable; + +import org.eclipse.osgi.service.debug.DebugOptions; +import org.eclipse.osgi.service.debug.DebugOptionsListener; +import org.eclipse.osgi.service.debug.DebugTrace; +import org.osgi.framework.BundleContext; + +/** + * Hooks debug options to the Platform trace functionality. + * In essence, we can open Window -> Preferences -> Tracing + * and turn on debug options for this package. The debug output + * will come out on the console and can be saved directly to + * a file. Classes that need to be debugged can call into + * TraceOptions to get debug flags. If new flags need to be + * created, they will need to have a unique identifier and added to + * the .options file in this plugin + * + */ +class TraceOptions implements DebugOptionsListener { + + private static final String DEBUG_FLAG = "org.eclipse.cdt.debug.ui.memory.traditional/debug"; //$NON-NLS-1$ + + public static boolean DEBUG = false; + + /** + * The {@link DebugTrace} object to print to OSGi tracing + */ + private static DebugTrace fgDebugTrace; + private String pluginID; + + /** + * Constructor + */ + public TraceOptions(BundleContext context, String pluginID) { + this.pluginID = pluginID; + Hashtable props = new Hashtable(2); + props.put(org.eclipse.osgi.service.debug.DebugOptions.LISTENER_SYMBOLICNAME, pluginID); + context.registerService(DebugOptionsListener.class.getName(), this, props); + } + + + @Override + public void optionsChanged(DebugOptions options) { + fgDebugTrace = options.newDebugTrace(pluginID); + DEBUG = options.getBooleanOption(DEBUG_FLAG, false); + } + + /** + * Prints the given message to System.out and to the OSGi tracing (if started) + * @param option the option or null + * @param message the message to print or null + * @param throwable the {@link Throwable} or null + */ + public static void trace(String option, String message, Throwable throwable) { + //divide the string into substrings of 100 chars or less for printing + //to console + String systemPrintableMessage = message; + while (systemPrintableMessage.length() > 100) { + String partial = systemPrintableMessage.substring(0, 100); + systemPrintableMessage = systemPrintableMessage.substring(100); + System.out.println(partial + "\\"); //$NON-NLS-1$ + } + System.out.print(systemPrintableMessage); + //then pass the original message to be traced into a file + if(fgDebugTrace != null) { + fgDebugTrace.trace(option, message, throwable); + } + } + + /** + * Prints the given message to System.out and to the OSGi tracing (if enabled) + * + * @param message the message or null + */ + public static void trace(String message) { + trace(null, message, null); + } + + +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPlugin.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPlugin.java index 18720fddbf0..6675c6ca2b1 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPlugin.java +++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006-2009 Wind River Systems, Inc. and others. + * Copyright (c) 2006-2015 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -16,6 +16,7 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; public class TraditionalRenderingPlugin extends AbstractUIPlugin { @@ -29,6 +30,12 @@ public class TraditionalRenderingPlugin extends AbstractUIPlugin plugin = this; } + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + new TraceOptions(context, PLUGIN_ID); + } + /** * Returns the shared instance. */ @@ -68,5 +75,5 @@ public class TraditionalRenderingPlugin extends AbstractUIPlugin return window.getShell(); } return null; - } + } }