[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-patch] HexEditor // Hex viewer patch
|
All,
This is a patch which will provide a basic hd like hex
editor/dump. I thought that it would be best rolled into
the CDT since it is something that C developers tend to use
a fair bit. It is currently a rough work in progress but
it works well enough that it suits my needs.
Limitations:
- Read only currently
- Not the most intelligent drawing mechanism (too much flash)
- Requires you to select a fixed width font in the preferences.
Other than that it works well for me. Would the CDT community
at large be interested? I've attached a patch + zip file
that would be my proposed changes. The zip is of the entire
CDT.ui tree and includes new icons and the new source code.
Thanks,
Thomas
-------------------------------------------------------------
Thomas (toe-mah) Fletcher QNX Software Systems
thomasf@xxxxxxx OS Technology Developer
(613)-591-0931 http://www.qnx.com/
Attachment:
hexedit.zip
Description: Zip archive
? src/org/eclipse/cdt/internal/ui/editor/hex
? src/org/eclipse/cdt/internal/ui/editor/hex
? src/org/eclipse/cdt/internal/ui/editor/hex
? src/org/eclipse/cdt/internal/ui/editor/hex
Index: plugin.xml
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/plugin.xml,v
retrieving revision 1.10
diff -u -r1.10 plugin.xml
--- plugin.xml 30 Sep 2002 13:30:58 -0000 1.10
+++ plugin.xml 23 Oct 2002 14:36:59 -0000
@@ -29,9 +29,9 @@
<extension-point id="CCompletionContributor" name="%completionContributorName"/>
<extension-point id="CElementFilters" name="%elementFiltersName"/>
<!-- =========================================================================== -->
-<!-- Extension Implementation: must implement org.eclipse.jface.text.ITextHover -->
-<!-- Purpose: Provide a perspective specific text hovering for CEditor files -->
<!-- Extension point: org.eclipse.cdt.ui.textHovers -->
+<!-- Purpose: Provide a perspective specific text hovering for CEditor files -->
+<!-- Extension Implementation: must implement org.eclipse.jface.text.ITextHover -->
<!-- =========================================================================== -->
<extension-point id="textHovers" name="%textHoversName"/>
@@ -132,8 +132,8 @@
id="org.eclipse.cdt.ui.CView">
</view>
</extension>
-<!-- The wizards -->
<!-- For C Wizards -->
+<!-- The wizards -->
<extension
point="org.eclipse.ui.newWizards">
<category
@@ -233,6 +233,12 @@
class="org.eclipse.cdt.internal.ui.editor.asm.AsmTextEditor"
id="org.eclipse.cdt.ui.editor.asm.AsmEditor">
</editor>
+ <editor
+ name="Hex Editor"
+ icon="icons/full/obj16/hex_file_obj.gif"
+ class="org.eclipse.cdt.internal.ui.editor.hex.HexEditor"
+ id="org.eclipse.cdt.ui.internal.editor.hex">
+ </editor>
</extension>
<extension
point="org.eclipse.ui.preferencePages">
@@ -253,6 +259,11 @@
class="org.eclipse.cdt.internal.ui.preferences.TemplatePreferencePage"
id="org.eclipse.cdt.ui.preferences.TemplatePreferencePage">
</page>
+ <page
+ name="Hex Editor"
+ class="org.eclipse.cdt.internal.ui.editor.hex.HexEditorPreferencePage"
+ id="org.eclipse.cdt.ui.internal.editor.hex.page">
+ </page>
</extension>
<extension
point="org.eclipse.ui.propertyPages">
@@ -282,14 +293,6 @@
</editorContribution>
</extension>
<!--
- <page
- objectClass="org.eclipse.core.resources.IFile"
- name="%CLaunchingPropertyPage.executionArguments.name"
- class="org.eclipse.cdt.internal.ui.preferences.CLaunchingPropertyPage"
- id="org.eclipse.cdt.ui.preferences.CLaunchingPropertyPage">
- </page>
--->
-<!--
<extension
point="org.eclipse.debug.core.launchers">
<launcher
@@ -302,6 +305,14 @@
id="org.eclipse.cdt.core.CApplicationLauncher">
</launcher>
</extension>
+-->
+<!--
+ <page
+ objectClass="org.eclipse.core.resources.IFile"
+ name="%CLaunchingPropertyPage.executionArguments.name"
+ class="org.eclipse.cdt.internal.ui.preferences.CLaunchingPropertyPage"
+ id="org.eclipse.cdt.ui.preferences.CLaunchingPropertyPage">
+ </page>
-->
<extension
point="org.eclipse.ui.popupMenus">
Index: icons/full/obj16/hex_file_obj.gif
===================================================================
RCS file: icons/full/obj16/hex_file_obj.gif
diff -N icons/full/obj16/hex_file_obj.gif
Binary files /dev/null and hex_file_obj.gif differ
Index: src/org/eclipse/cdt/internal/ui/CPlugin.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPlugin.java,v
retrieving revision 1.7
diff -u -r1.7 CPlugin.java
--- src/org/eclipse/cdt/internal/ui/CPlugin.java 16 Oct 2002 20:14:22 -0000 1.7
+++ src/org/eclipse/cdt/internal/ui/CPlugin.java 23 Oct 2002 14:37:00 -0000
@@ -17,6 +17,7 @@
import org.eclipse.cdt.internal.ui.cview.CView;
import org.eclipse.cdt.internal.ui.editor.CDocumentProvider;
import org.eclipse.cdt.internal.ui.editor.asm.AsmTextTools;
+import org.eclipse.cdt.internal.ui.editor.hex.HexEditorPreferencePage;
import org.eclipse.cdt.internal.ui.preferences.CEditorPreferencePage;
import org.eclipse.cdt.internal.ui.preferences.CPluginPreferencePage;
import org.eclipse.cdt.internal.ui.text.CTextTools;
@@ -317,6 +318,7 @@
public void run() {
CPluginPreferencePage.initDefaults(store);
CEditorPreferencePage.initDefaults(store);
+ HexEditorPreferencePage.initDefaults(store);
CView.initDefaults(store);
}
});
Index: src/org/eclipse/cdt/internal/ui/editor/HexEditor.java
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/editor/HexEditor.java
diff -N src/org/eclipse/cdt/internal/ui/editor/HexEditor.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/editor/HexEditor.java 23 Oct 2002 14:37:02 -0000
@@ -0,0 +1,118 @@
+package org.eclipse.cdt.internal.ui.editor.hex;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.part.EditorPart;
+
+/**
+ * Insert the type's description here.
+ * @see EditorPart
+ */
+public class HexEditor extends EditorPart {
+ IEditorSite fEdSite;
+ IEditorInput fEdInput; //This is really an IFileEditorInput
+ IFile event_file;
+ HexTextDisplay fHexDisplay;
+
+ /**
+ * The constructor.
+ */
+ public HexEditor() {
+ }
+
+ /**
+ * Insert the method's description here.
+ * @see EditorPart#createPartControl
+ */
+ public void createPartControl(Composite parent) {
+ fHexDisplay = new HexTextDisplay(parent, SWT.NONE);
+
+ if(!(fEdInput instanceof IFileEditorInput)) {
+ return;
+ }
+
+ IFile file = ((IFileEditorInput)fEdInput).getFile();
+ try {
+ fHexDisplay.setInput(file.getLocation().toOSString());
+ } catch (FileNotFoundException e) {
+ } catch (IOException e) {
+ }
+ }
+
+ /**
+ * Insert the method's description here.
+ * @see EditorPart#setFocus
+ */
+ public void setFocus() {
+ fHexDisplay.setFocus();
+ }
+
+ /**
+ * Insert the method's description here.
+ * @see EditorPart#gotoMarker
+ */
+ public void gotoMarker(IMarker marker) {
+ }
+
+ /**
+ * Insert the method's description here.
+ * @see EditorPart#init
+ */
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+ fEdSite = site;
+ fEdInput = input;
+ setSite(site);
+ setTitle(input.getName() + " (Read only)");
+ }
+
+
+
+ /**
+ * Insert the method's description here.
+ * @see EditorPart#isDirty
+ */
+ public boolean isDirty() {
+ return false;
+ }
+
+ /**
+ * Insert the method's description here.
+ * @see EditorPart#isSaveAsAllowed
+ */
+ public boolean isSaveAsAllowed() {
+ return false;
+ }
+
+ /**
+ * Insert the method's description here.
+ * @see EditorPart#doSave
+ */
+ public void doSave(IProgressMonitor monitor) {
+ }
+
+ /**
+ * Insert the method's description here.
+ * @see EditorPart#doSaveAs
+ */
+ public void doSaveAs() {
+ }
+
+ /**
+ * @see org.eclipse.ui.IWorkbenchPart#dispose()
+ */
+ public void dispose() {
+ fHexDisplay.dispose();
+ super.dispose();
+ }
+
+}
Index: src/org/eclipse/cdt/internal/ui/editor/HexEditorPreferencePage.java
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/editor/HexEditorPreferencePage.java
diff -N src/org/eclipse/cdt/internal/ui/editor/HexEditorPreferencePage.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/editor/HexEditorPreferencePage.java 23 Oct 2002 14:37:02 -0000
@@ -0,0 +1,110 @@
+package org.eclipse.cdt.internal.ui.editor.hex;
+
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.cdt.internal.ui.CPlugin;
+import org.eclipse.jface.preference.ColorFieldEditor;
+import org.eclipse.jface.preference.FieldEditor;
+import org.eclipse.jface.preference.FontFieldEditor;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/**
+ * Insert the type's description here.
+ * @see PreferencePage
+ */
+public class HexEditorPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+ FontFieldEditor ffe;
+ ColorFieldEditor linefe;
+ ColorFieldEditor selfe;
+
+ /**
+ * The constructor.
+ */
+ public HexEditorPreferencePage() {
+ }
+
+ /**
+ * Insert the method's description here.
+ * @see PreferencePage#init
+ */
+ public void init(IWorkbench workbench) {
+ setPreferenceStore(CPlugin.getDefault().getPreferenceStore());
+ }
+
+ /**
+ * Insert the method's description here.
+ * @see PreferencePage#createContents
+ */
+ protected Control createContents(Composite parent) {
+ Composite control = new Composite(parent, SWT.NONE);
+ control.setLayout(new GridLayout(3, false));
+ control.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
+
+ linefe = new ColorFieldEditor(IHexEditorConstants.PREF_HEXEDIT_LINECOLOR,
+ "Line Colour",
+ control);
+ setFieldEditorSettings(linefe);
+ Label filler = new Label(control, SWT.NONE);
+ filler.setText("");
+
+ selfe = new ColorFieldEditor(IHexEditorConstants.PREF_HEXEDIT_SELCOLOR,
+ "Selection Colour",
+ control);
+ setFieldEditorSettings(selfe);
+ filler = new Label(control, SWT.NONE);
+
+ ffe = new FontFieldEditor(IHexEditorConstants.PREF_HEXEDIT_FONT,
+ "Editor font",
+ control);
+ setFieldEditorSettings(ffe);
+
+ return control;
+ }
+
+ private void setFieldEditorSettings(FieldEditor fe) {
+ fe.setPreferencePage(this);
+ fe.setPreferenceStore(getPreferenceStore());
+ fe.load();
+ }
+
+ /**
+ * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+ */
+ protected void performDefaults() {
+ ffe.loadDefault();
+ linefe.loadDefault();
+ selfe.loadDefault();
+ super.performDefaults();
+ }
+
+ /**
+ * @see org.eclipse.jface.preference.IPreferencePage#performOk()
+ */
+ public boolean performOk() {
+ ffe.store();
+ linefe.store();
+ selfe.store();
+ return super.performOk();
+ }
+
+ public static void initDefaults(IPreferenceStore store) {
+ FontData [] list = CPlugin.getActiveWorkbenchShell().getDisplay().getFontList("courier", true);
+
+ if(list != null && list.length > 0) {
+ PreferenceConverter.setDefault(store, IHexEditorConstants.PREF_HEXEDIT_FONT, list);
+ }
+
+ PreferenceConverter.setDefault(store, IHexEditorConstants.PREF_HEXEDIT_LINECOLOR, new RGB(225, 235, 224));
+ PreferenceConverter.setDefault(store, IHexEditorConstants.PREF_HEXEDIT_SELCOLOR, new RGB(125, 135, 124));
+ }
+}
Index: src/org/eclipse/cdt/internal/ui/editor/HexTextDisplay.java
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/editor/HexTextDisplay.java
diff -N src/org/eclipse/cdt/internal/ui/editor/HexTextDisplay.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/editor/HexTextDisplay.java 23 Oct 2002 14:37:02 -0000
@@ -0,0 +1,615 @@
+package org.eclipse.cdt.internal.ui.editor.hex;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.text.DecimalFormat;
+import java.util.Arrays;
+
+import org.eclipse.cdt.internal.ui.CPlugin;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.*;
+//import org.eclipse.swt.custom.*;
+import org.eclipse.swt.events.*;
+//import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.graphics.*;
+
+
+/**
+ * This is a custom widget put together for the sole purpose of being
+ * able to implement efficient drawing for the trace event data.
+ */
+public class HexTextDisplay extends Composite implements IPropertyChangeListener {
+ static final String TEST_LINE = "00000000 AB CD EF AB AB CD EF AB AB CD EF AB AB CD EF AB 1234567890123456";
+ static final String TEST_OFFSET = "00000000";
+ static final String TEST_HEXVAL = "AB CD EF AB AB CD EF AB AB CD EF AB AB CD EF AB";
+ static final String TEST_CHARVAL = "1234567890123456";
+ static final String FORMAT_OFFSET = "00000000";
+ static final int VSPACER = 2;
+ static final int LOWER_CHAR_DISPLAY_BOUND = 32;
+ static final int UPPER_CHAR_DISPLAY_BOUND = 127;
+
+ static final int MOUSE_DOWN = 1;
+ static final int MOUSE_UP = 2;
+ static final int KEY_UP = 1;
+ static final int KEY_DOWN = 2;
+
+ long fDataLength; //Length of data (in bytes)
+ long fVStartOffset; //Visual start offset from start of stream (in bytes)
+ int fVStartCharIndex; //Visual start character
+ int fBytesPerLine; //Number of bytes per line
+
+ long fCursorHighlight; //Cursor position (in bytes)
+ int fCursorNibble; //Top or lower nibble
+ boolean fHighlightHex; //Highlight the hex values (else the chars)
+
+
+ RandomAccessFile fFile;
+ IPreferenceStore fPrefStore;
+
+ //UI components
+ Canvas fCanvas;
+ Slider fVScroll;
+ Slider fHScroll;
+ Image fOffscreenImage;
+
+ //Driven by preferences
+ Font fTextFont;
+ RGB fLineRGB;
+ RGB fSelRGB;
+
+ /**
+ * This is the layout class for the trace graph widget.
+ */
+ class HexEditorLayout extends Layout {
+ int hpadding = 1;
+ int vpadding = 1;
+ int borderWidth = 1;
+
+ int scrollwh = 10;
+
+ /**
+ * Computes the preferred size.
+ */
+ public Point computeSize(Composite parent, int wHint, int hHint, boolean flushCache) {
+ Rectangle bounds = HexTextDisplay.this.getClientArea();
+
+ Point pt = new Point(bounds.width, bounds.height);
+ return pt;
+ }
+
+ public void layout(Composite parent, boolean flushCache) {
+ Rectangle bounds = HexTextDisplay.this.getClientArea();
+
+ Point pt;
+ pt = fHScroll.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ scrollwh = pt.y;
+ //pt = fCanvas.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+
+ fCanvas.setBounds(bounds.x, bounds.y, bounds.width - scrollwh, bounds.height - scrollwh);
+
+ fHScroll.setBounds(bounds.x,
+ bounds.y + bounds.height - scrollwh,
+ bounds.width - scrollwh,
+ scrollwh);
+
+ fVScroll.setBounds(bounds.x + bounds.width - scrollwh,
+ bounds.y,
+ scrollwh,
+ bounds.height - scrollwh);
+ }
+ }
+
+ /**
+ * This is essentially everything we need to build a
+ * trace graph.
+ */
+ public HexTextDisplay(Composite parent, int style) {
+ super(parent, 0);
+
+ fCanvas= new Canvas(this, SWT.NONE);
+ fCanvas.setBackground(new Color(null, 255, 255, 255));
+ fCanvas.addPaintListener(new PaintListener() {
+ public void paintControl(PaintEvent e) {
+ HexTextDisplay.this.paintEditor(e);
+ }
+ });
+ fCanvas.addControlListener(new ControlAdapter() {
+ public void controlResized(ControlEvent e) {
+ HexTextDisplay.this.resizeEditor(e);
+ }
+ });
+ fCanvas.addMouseListener(new MouseAdapter() {
+ public void mouseDown(MouseEvent e) {
+ HexTextDisplay.this.mouseEvent(e, MOUSE_DOWN);
+ }
+ public void mouseUp(MouseEvent e) {
+ HexTextDisplay.this.mouseEvent(e, MOUSE_UP);
+ }
+ });
+ fCanvas.addMouseMoveListener(new MouseMoveListener() {
+ public void mouseMove(MouseEvent e) {
+ //TraceGraph.this.mouseGraph(e, MOUSE_MOVE);
+ }
+ });
+ fCanvas.addKeyListener(new KeyAdapter() {
+ public void keyReleased(KeyEvent e) {
+ //TraceGraph.this.keyReleased(e);
+ }
+ public void keyPressed(KeyEvent e) {
+ HexTextDisplay.this.keyEvent(e, KEY_DOWN);
+ }
+ });
+ fCanvas.addListener(SWT.MouseHover, new Listener() {
+ public void handleEvent(Event e) {
+ }
+ });
+
+ fVScroll = new Slider(this, SWT.VERTICAL);
+ fVScroll.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ HexTextDisplay.this.scrollEditor(e);
+ }
+ });
+ fVScroll.setIncrement(1);
+
+ fHScroll = new Slider(this, SWT.HORIZONTAL);
+ fHScroll.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ HexTextDisplay.this.scrollEditor(e);
+ }
+ });
+ fHScroll.setIncrement(1);
+
+ setLayout(new HexEditorLayout());
+
+ //Suck the data from the preferences
+ fPrefStore = CPlugin.getDefault().getPreferenceStore();
+ fPrefStore.addPropertyChangeListener(this);
+
+ //Fire a fake change to initialize ourselves
+ propertyChange(null);
+ }
+
+ public void dispose() {
+ if(fFile != null) {
+ try {
+ fFile.close();
+ } catch(Exception ex) {
+ /* Ignore */
+ }
+ }
+ fPrefStore.removePropertyChangeListener(this);
+ super.dispose();
+ }
+
+ public void propertyChange(PropertyChangeEvent event) {
+ boolean redraw = false;
+ if(event == null || event.getProperty().equals(IHexEditorConstants.PREF_HEXEDIT_FONT)) {
+ fTextFont = new Font(null, PreferenceConverter.getFontData(fPrefStore, IHexEditorConstants.PREF_HEXEDIT_FONT));
+ fCanvas.setFont(fTextFont);
+ redraw = true;
+ }
+ if(event == null || event.getProperty().equals(IHexEditorConstants.PREF_HEXEDIT_LINECOLOR)) {
+ fLineRGB = PreferenceConverter.getColor(fPrefStore, IHexEditorConstants.PREF_HEXEDIT_LINECOLOR);
+ redraw = true;
+ }
+ if(event == null || event.getProperty().equals(IHexEditorConstants.PREF_HEXEDIT_SELCOLOR)) {
+ fSelRGB = PreferenceConverter.getColor(fPrefStore, IHexEditorConstants.PREF_HEXEDIT_SELCOLOR);
+ redraw = true;
+ }
+
+ if(redraw) {
+ fCanvas.redraw();
+ }
+ }
+
+
+ public void setInput(String filename) throws FileNotFoundException, IOException {
+ fFile = new RandomAccessFile(filename, "r");
+
+ fDataLength = fFile.length();
+ fVStartOffset = 0;
+ fVStartCharIndex = 0;
+ fBytesPerLine = 16;
+
+ fCanvas.redraw();
+ }
+
+ /**
+ * Retrieve the currently highlighted position.
+ */
+ public long getCurrentOffset() {
+ return fCursorHighlight;
+ }
+
+ protected void scrollEditor(SelectionEvent ev) {
+ //Find the start line
+ int yscroll = fVScroll.getSelection();
+ fVStartOffset = yscroll * fBytesPerLine;
+
+ //Find the y start character
+ int xscroll = fHScroll.getSelection();
+ fVStartCharIndex = xscroll;
+
+ fCanvas.redraw();
+ }
+
+ //@@@ TODO:
+ // In the future, we should only draw the background and then
+ // xor/overlay the currently selected position on top.
+ protected void paintEditor(PaintEvent ev) {
+ if(fOffscreenImage != null) {
+ drawOffScreen();
+ ev.gc.drawImage(fOffscreenImage, 0, 0);
+ }
+ }
+
+ /**
+ * This will clear the offscreen image and then draw the hex values on it.
+ */
+ protected void drawOffScreen() {
+ GC gc = new GC(fOffscreenImage);
+ Color backclr = new Color(null, 255, 255, 255);
+
+ gc.setBackground(backclr);
+ gc.fillRectangle(fOffscreenImage.getBounds());
+ backclr.dispose();
+
+ gc.setFont(fTextFont);
+ drawHexValues(gc);
+
+ gc.dispose();
+ }
+
+ /**
+ * This is use to seperate out the "how" aspect of the drawing from the "where"
+ * so that we can choose to do this offscreen or on screen as we so desire. It
+ * also gives us a point of seperation for later drawing things like markers
+ * and user selections.
+ *
+ * @@@ TODO Remove the reliance on a fixed width font.
+ */
+ protected void drawHexValues(GC gc) {
+ Rectangle bounds = fCanvas.getClientArea();
+
+ if(fFile == null) {
+ return;
+ }
+
+ //@@@ Move much of these constants to the resize callback
+
+ //Decide how many lines we can draw
+ Point pt = gc.stringExtent(TEST_LINE);
+ int fLineNum = bounds.height/(pt.y + VSPACER);
+
+ //Calculate the positional offsets
+ int xstartoff = -1 * (fVStartCharIndex * gc.stringExtent(" ").x);
+ int offsetwidth = gc.stringExtent(TEST_OFFSET).x;
+ int hexvalwidth = gc.stringExtent(TEST_HEXVAL).x;
+
+// int charvalwidth = gc.stringExtent(TEST_CHARVAL).x;
+ int spacerwidth = gc.stringExtent(" ").x;
+
+ Color clr = new Color(null, fLineRGB);
+ gc.setBackground(clr);
+ gc.fillRectangle(xstartoff, 0, offsetwidth, bounds.height);
+ clr.dispose();
+
+ byte [] inputChars = new byte[fBytesPerLine];
+ StringBuffer outputLine = new StringBuffer();
+
+ DecimalFormat lineFmt = new DecimalFormat(FORMAT_OFFSET);
+
+ //Draw those lines
+
+ int yOffset = 0;
+ long fileOffset = fVStartOffset;
+ for(int i = 0; i < fLineNum; i++) {
+ fileOffset = fVStartOffset + (i*fBytesPerLine);
+ if(fileOffset >= fDataLength) {
+ break;
+ }
+
+ //Determine which characters to highlight
+ if((fCursorHighlight >= fileOffset) &&
+ (fCursorHighlight < (fileOffset + fBytesPerLine))) {
+ int hexCurOff, hexCurWidth;
+ int charCurOff, charCurWidth;
+
+ hexCurWidth = gc.stringExtent("A").x;
+ hexCurOff = offsetwidth + spacerwidth;
+ hexCurOff += (fCursorHighlight - fileOffset) * (gc.stringExtent("AB ").x);
+
+ charCurWidth = gc.stringExtent(" ").x;
+ charCurOff = offsetwidth + hexvalwidth + (2 * spacerwidth);
+ charCurOff += (fCursorHighlight - fileOffset) * charCurWidth;
+
+ Color primary = new Color(null, fSelRGB);
+ Color secondary = new Color(null, fLineRGB);
+
+ if(fHighlightHex) {
+ gc.setBackground(primary);
+ gc.drawRectangle(xstartoff + hexCurOff, yOffset, 2 * hexCurWidth, pt.y);
+ if(fCursorNibble == 0) {
+ gc.fillRectangle(xstartoff + hexCurOff, yOffset, hexCurWidth, pt.y);
+ } else {
+ gc.fillRectangle(xstartoff + hexCurOff + hexCurWidth, yOffset, hexCurWidth, pt.y);
+ }
+ } else {
+ gc.setBackground(secondary);
+ gc.fillRectangle(xstartoff + hexCurOff, yOffset, 2 * hexCurWidth, pt.y);
+ }
+
+ gc.setBackground((fHighlightHex) ? secondary : primary);
+ gc.fillRectangle(xstartoff + charCurOff, yOffset, charCurWidth, pt.y);
+
+ primary.dispose();
+ secondary.dispose();
+ }
+
+ //Draw the rest of the string on top
+ int numBytes = 0;
+ try {
+ Arrays.fill(inputChars, (byte)0);
+ fFile.seek(fileOffset);
+ numBytes = fFile.read(inputChars);
+ } catch(Exception ex) {
+ System.out.println("Exception seeking/reading");
+ numBytes = -1;
+ }
+
+ if(numBytes == -1) {
+ break;
+ }
+
+ //Byte offset
+ outputLine.append(lineFmt.format(fileOffset));
+ outputLine.append(" ");
+
+ //Hex values
+ for(int j = 0; j < inputChars.length; j++) {
+ if(j < numBytes) {
+ outputLine.append(makeHexByte(inputChars[j]));
+ } else {
+ outputLine.append(" ");
+ }
+ outputLine.append(" ");
+ }
+
+ outputLine.append(" ");
+
+ //Char values
+ for(int j = 0; j < numBytes; j++) {
+ char ch = (char)(((char)inputChars[j]) & 0xff);
+ if(ch >= LOWER_CHAR_DISPLAY_BOUND && ch <= UPPER_CHAR_DISPLAY_BOUND) {
+ outputLine.append(ch);
+ } else {
+ outputLine.append(".");
+ }
+ }
+
+ gc.drawText(outputLine.toString(), xstartoff, yOffset, true);
+ yOffset += pt.y + VSPACER;
+
+ outputLine.delete(0, outputLine.length());
+ }
+ }
+
+ protected void resizeEditor(ControlEvent ev) {
+ Rectangle area = fCanvas.getClientArea();
+
+ GC gc = new GC(fCanvas);
+ int textWidth = gc.stringExtent(TEST_LINE).x;
+ int textHeight = gc.stringExtent(TEST_LINE).y + VSPACER;
+ int oneCharWidth = gc.stringExtent(" ").x;
+ gc.dispose();
+
+ //Set the horizontal scroll
+ int numCharsTotal = TEST_LINE.length();
+ if(area.width >= textWidth) {
+ fHScroll.setSelection(0);
+ fHScroll.setEnabled(false);
+ } else {
+ fHScroll.setMinimum(0);
+ int max = numCharsTotal - (area.width / oneCharWidth);
+ fHScroll.setMaximum(max + fHScroll.getThumb());
+ fHScroll.setEnabled(true);
+ }
+
+ //Set the vertical scroll
+ int numLinesTotal = (int)(fDataLength / (long)fBytesPerLine) + 1;
+ int allLinesHeight = numLinesTotal * textHeight;
+ if(area.height >= allLinesHeight) {
+ fVScroll.setSelection(0);
+ fVScroll.setEnabled(false);
+ } else {
+ fVScroll.setMinimum(0);
+ int max = numLinesTotal - (area.height / textHeight);
+ fVScroll.setMaximum(max + fVScroll.getThumb());
+ fVScroll.setEnabled(true);
+ }
+
+ //Resize the offscreen image
+ if(fOffscreenImage != null) {
+ fOffscreenImage.dispose();
+ fOffscreenImage = null;
+ }
+ if(!isDisposed() && area.width > 0 && area.height > 0) {
+ fOffscreenImage = new Image(null, area);
+ }
+
+ scrollEditor(null);
+ }
+
+ protected void mouseEvent(MouseEvent ev, int state) {
+ Rectangle bounds = fCanvas.getClientArea();
+ GC gc = new GC(fCanvas);
+
+ Point pt = gc.stringExtent(TEST_LINE);
+ int fLineNum = bounds.height/(pt.y + VSPACER);
+
+ //Calculate the positional offsets
+ int xstartoff = -1 * (fVStartCharIndex * gc.stringExtent(" ").x);
+ int offsetwidth = gc.stringExtent(TEST_OFFSET).x;
+ int hexvalwidth = gc.stringExtent(TEST_HEXVAL).x;
+ int charvalwidth = gc.stringExtent(TEST_CHARVAL).x;
+ int spacerwidth = gc.stringExtent(" ").x;
+ gc.dispose();
+
+ if(state == MOUSE_DOWN) {
+ fLineNum = ev.y / (pt.y + VSPACER);
+
+ if(ev.x <= (xstartoff + offsetwidth + spacerwidth)) {
+ ; //Ignore clicks in offset column
+ } else if (ev.x <= (xstartoff + offsetwidth + hexvalwidth + (2 * spacerwidth))) {
+ //Hex value selection
+ ev.x -= xstartoff + offsetwidth + spacerwidth;
+
+ fCursorHighlight = fVStartOffset;
+ fCursorHighlight += fLineNum * fBytesPerLine;
+ fCursorHighlight += (ev.x * fBytesPerLine) / hexvalwidth;
+ fCursorNibble = 0;
+ fHighlightHex = true;
+
+ fCanvas.redraw();
+ } else if (ev.x <= (xstartoff + offsetwidth + hexvalwidth + charvalwidth + (2 * spacerwidth))) {
+ //Character value selection;
+ ev.x -= xstartoff + offsetwidth + hexvalwidth + (2 * spacerwidth);
+
+ fCursorHighlight = fVStartOffset;
+ fCursorHighlight += fLineNum * fBytesPerLine;
+ fCursorHighlight += (ev.x * fBytesPerLine) / charvalwidth;
+ fHighlightHex = false;
+
+ fCanvas.redraw();
+ }
+ }
+
+ }
+
+ protected void keyEvent(KeyEvent ev, int state) {
+ long orgHighlight = fCursorHighlight;
+ int orgNibble = fCursorNibble;
+
+ if(ev.keyCode != 0) {
+ switch(ev.keyCode) {
+ case SWT.ARROW_UP:
+ fCursorHighlight -= (fCursorHighlight >= fBytesPerLine) ? fBytesPerLine : 0;
+ break;
+ case SWT.ARROW_DOWN:
+ fCursorHighlight += (fCursorHighlight <= fDataLength - fBytesPerLine) ? fBytesPerLine : 0;
+ break;
+ case SWT.ARROW_LEFT:
+ if(fHighlightHex == false) {
+ fCursorHighlight -= (fCursorHighlight > 0) ? 1 : 0;
+ } else if(fCursorNibble == 0) {
+ fCursorNibble = 1;
+ fCursorHighlight -= (fCursorHighlight > 0) ? 1 : 0;
+ } else {
+ fCursorNibble = 0;
+ }
+ break;
+ case SWT.ARROW_RIGHT:
+ if(fHighlightHex == false) {
+ fCursorHighlight += (fCursorHighlight < fDataLength - 1) ? 1 : 0;
+ } else if(fCursorNibble == 1) {
+ fCursorHighlight += (fCursorHighlight < fDataLength - 1) ? 1 : 0;
+ fCursorNibble = 0;
+ } else {
+ fCursorNibble = 1;
+ }
+ break;
+ }
+
+ if(orgHighlight != fCursorHighlight || orgNibble != fCursorNibble) {
+ ensureCursorVisible(false);
+ fCanvas.redraw();
+ }
+ } else {
+//TODO: Add editing capabilities
+// //Edit the file limited by the entries we make
+// if(fHighlightHex) {
+// if((ev.character >= 'a' && ev.character <= 'z') ||
+// (ev.character >= '0' && ev.character <= '9') ||
+// (ev.character >= 'A' && ev.character <= 'Z')) {
+// } else {
+// getDisplay().beep();
+// }
+// } else {
+// if(ev.character >= LOWER_CHAR_DISPLAY_BOUND && ev.character <= UPPER_CHAR_DISPLAY_BOUND) {
+// try {
+// fFile.seek(fCursorHighlight);
+// fFile.write((byte)ev.character);
+// } catch(Exception e) {
+// /* Ignore */
+// }
+// fCanvas.redraw();
+// } else {
+// getDisplay().beep();
+// }
+// }
+ }
+
+ }
+
+ /**
+ * Recalculates the start/end indices based on making the highlighted
+ * cursor visible. Does not cause a re-draw operation to occur.
+ * @param center Setting center to true causes the display to center on the
+ * cursor position if it is not visible, otherwise it will appear as the first
+ * or last line of the editor.
+ *
+ * @@@ TODO: Support horizontal scrolling as well
+ */
+ protected void ensureCursorVisible(boolean center) {
+ GC gc = new GC(fCanvas);
+ Rectangle bounds = fCanvas.getClientArea();
+ Point pt = gc.stringExtent(TEST_LINE);
+ int fLineNum = bounds.height/(pt.y + VSPACER);
+ gc.dispose();
+
+ long tempPosition = 0;
+ if(fCursorHighlight < fVStartOffset) {
+ if(center) {
+ tempPosition = (fCursorHighlight - ((fLineNum / 2) * fBytesPerLine));
+ } else {
+ tempPosition = fCursorHighlight;
+ }
+ } else if(fCursorHighlight >= (fVStartOffset + (fLineNum * fBytesPerLine))) {
+ //Adjust for the fact that our current position consumes one line
+ if(center) {
+ tempPosition = (fCursorHighlight - (((fLineNum / 2) - 1) * fBytesPerLine));
+ } else {
+ tempPosition = (fCursorHighlight - ((fLineNum -1) * fBytesPerLine));
+ }
+ } else {
+ return;
+ }
+
+ if(tempPosition <= 0) {
+ fVStartOffset = 0;
+ } else {
+ fVStartOffset = tempPosition - (tempPosition % fBytesPerLine);
+ }
+ }
+
+ /**
+ * This is used as a simple way to make a two char hex string value from a single byte.
+ */
+ private String makeHexByte(byte b) {
+ int a = ((int)b) & 0xff;
+ String s = Integer.toHexString(a);
+
+ if(s.length() < 2) {
+ return "0" + s;
+ } else {
+ return s;
+ }
+ }
+}
+
Index: src/org/eclipse/cdt/internal/ui/editor/IHexEditorConstants.java
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/editor/IHexEditorConstants.java
diff -N src/org/eclipse/cdt/internal/ui/editor/IHexEditorConstants.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/editor/IHexEditorConstants.java 23 Oct 2002 14:37:02 -0000
@@ -0,0 +1,12 @@
+package org.eclipse.cdt.internal.ui.editor.hex;
+
+/**
+ * Constants related to the hex editor
+ */
+public interface IHexEditorConstants {
+ static String HEX_EDITOR_BASE_ID = "org.eclipse.cdt.internal.ui.editor.hex";
+
+ public static String PREF_HEXEDIT_FONT = HEX_EDITOR_BASE_ID + ".EDITORFONT";
+ public static String PREF_HEXEDIT_LINECOLOR = HEX_EDITOR_BASE_ID + ".EDITORLINE";
+ public static String PREF_HEXEDIT_SELCOLOR = HEX_EDITOR_BASE_ID + ".EDITORSEL";
+}