mirror of
https://github.com/peterdell/wudsn-ide.git
synced 2024-06-01 08:41:27 +00:00
630 lines
20 KiB
Java
630 lines
20 KiB
Java
/**
|
|
* Copyright (C) 2009 - 2021 <a href="https://www.wudsn.com" target="_top">Peter Dell</a>
|
|
*
|
|
* This file is part of WUDSN IDE.
|
|
*
|
|
* WUDSN IDE is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* WUDSN IDE is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package com.wudsn.ide.hex;
|
|
|
|
import java.io.File;
|
|
import java.util.Iterator;
|
|
|
|
import org.eclipse.core.resources.IFile;
|
|
import org.eclipse.core.runtime.CoreException;
|
|
import org.eclipse.core.runtime.IPath;
|
|
import org.eclipse.core.runtime.IProgressMonitor;
|
|
import org.eclipse.jface.action.MenuManager;
|
|
import org.eclipse.jface.viewers.ISelection;
|
|
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
|
import org.eclipse.jface.viewers.ISelectionProvider;
|
|
import org.eclipse.jface.viewers.IStructuredSelection;
|
|
import org.eclipse.jface.viewers.StyledString;
|
|
import org.eclipse.swt.SWT;
|
|
import org.eclipse.swt.custom.StyledText;
|
|
import org.eclipse.swt.events.FocusEvent;
|
|
import org.eclipse.swt.events.FocusListener;
|
|
import org.eclipse.swt.events.KeyEvent;
|
|
import org.eclipse.swt.events.KeyListener;
|
|
import org.eclipse.swt.graphics.Point;
|
|
import org.eclipse.swt.layout.FillLayout;
|
|
import org.eclipse.swt.layout.GridData;
|
|
import org.eclipse.swt.layout.GridLayout;
|
|
import org.eclipse.swt.widgets.Composite;
|
|
import org.eclipse.swt.widgets.Menu;
|
|
import org.eclipse.ui.IEditorInput;
|
|
import org.eclipse.ui.IEditorSite;
|
|
import org.eclipse.ui.IFileEditorInput;
|
|
import org.eclipse.ui.IPathEditorInput;
|
|
import org.eclipse.ui.PartInitException;
|
|
import org.eclipse.ui.part.EditorPart;
|
|
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
|
|
|
|
import com.wudsn.ide.base.BasePlugin;
|
|
import com.wudsn.ide.base.common.ByteArrayUtility;
|
|
import com.wudsn.ide.base.common.FileUtility;
|
|
import com.wudsn.ide.base.common.HexUtility;
|
|
import com.wudsn.ide.base.common.MessageQueue;
|
|
import com.wudsn.ide.base.common.NumberUtility;
|
|
import com.wudsn.ide.base.common.Profiler;
|
|
import com.wudsn.ide.base.common.TextUtility;
|
|
import com.wudsn.ide.base.gui.Action;
|
|
import com.wudsn.ide.base.gui.Application;
|
|
import com.wudsn.ide.base.gui.EnumField;
|
|
import com.wudsn.ide.base.gui.IntegerField;
|
|
import com.wudsn.ide.base.gui.MessageManager;
|
|
import com.wudsn.ide.base.gui.SWTFactory;
|
|
import com.wudsn.ide.base.gui.TextField;
|
|
import com.wudsn.ide.base.hardware.HardwareCharacterSet;
|
|
|
|
/**
|
|
* The Hex Editor. This editor offset and outline view for the block of the file
|
|
* and a context menu for copying the current selection clip board in different
|
|
* formats.
|
|
*
|
|
* TODO Complete copy & paste, complete documentation
|
|
*
|
|
* @author Peter Dell
|
|
*/
|
|
public final class HexEditor extends EditorPart implements ISelectionProvider, Application {
|
|
|
|
private static final String LABEL_SUFFIX = ": ";
|
|
|
|
public final class MessageIds {
|
|
|
|
/**
|
|
* Creation is private.
|
|
*/
|
|
private MessageIds() {
|
|
}
|
|
|
|
public static final int FILE_CONTENT_MODE = 1;
|
|
public static final int CHARACTER_SET = 2;
|
|
public static final int BYTES_PER_LINE = 3;
|
|
}
|
|
|
|
public final class Actions {
|
|
|
|
/**
|
|
* Creation is private.
|
|
*/
|
|
private Actions() {
|
|
}
|
|
|
|
public static final int FILE_CONTENT_MODE_CHANGED = 1000;
|
|
public static final int CHARACTER_SET_TYPE_CHANGED = 1001;
|
|
public static final int BYTES_PER_ROW_CHANGED = 1002;
|
|
}
|
|
|
|
public static final String ID = "com.wudsn.ide.hex.HexEditor";
|
|
|
|
private static final String CONTEXT_MENU_ID = "#HexEditorContext";
|
|
private static final long MAX_FILE_SIZE = 8 * ByteArrayUtility.MB;
|
|
|
|
private MessageQueue messageQueue;
|
|
private MessageManager messageManager;
|
|
private HexEditorParserComponent parserComponent;
|
|
|
|
// Editor content outline page.
|
|
private HexEditorContentOutlinePage contentOutlinePage;
|
|
|
|
// Editor header area.
|
|
private TextField fileContentSizeField;
|
|
private EnumField<HexEditorFileContentMode> fileContentModeField;
|
|
private EnumField<HardwareCharacterSet> characterSetField;
|
|
private IntegerField bytesPerRowField;
|
|
|
|
private StyledText textField;
|
|
private HexEditorSelection lastEditorSelection;
|
|
|
|
// File source.
|
|
private IFile iFile;
|
|
private File ioFile;
|
|
|
|
/**
|
|
* This main method is for testing the speed of the source file parser component
|
|
* only.
|
|
*
|
|
* @param args Not used, not <code>null</code>.
|
|
* @throws Exception If anything goes terribly wrong.
|
|
*/
|
|
public static void main(String[] args) throws Exception {
|
|
|
|
System.out.print("Testing HexEditorParserComponent: Parsing took ");
|
|
// Initialize for stand alone usage.
|
|
new BasePlugin().start(null);
|
|
|
|
HexEditorParserComponent parser = new HexEditorParserComponent(
|
|
new MessageManager(new MessageQueue(), new HexEditor()));
|
|
parser.setFileContent(new byte[100000]);
|
|
parser.determinePossibleFileContentModes();
|
|
|
|
long startTimeMillis = System.currentTimeMillis();
|
|
parser.setFileContentMode(HexEditorFileContentMode.BINARY);
|
|
parser.parseFileContent();
|
|
long duration = System.currentTimeMillis() - startTimeMillis;
|
|
System.out.println(duration + " ms");
|
|
System.exit(0);
|
|
|
|
}
|
|
|
|
/**
|
|
* Creation is public. Called by extension point "org.eclipse.ui.popupMenus".
|
|
*/
|
|
public HexEditor() {
|
|
super();
|
|
|
|
messageQueue = new MessageQueue();
|
|
messageManager = new MessageManager(messageQueue, this);
|
|
|
|
parserComponent = new HexEditorParserComponent(messageManager);
|
|
|
|
}
|
|
|
|
/**
|
|
* @see org.eclipse.ui.IEditorPart#init(IEditorSite, IEditorInput)
|
|
*/
|
|
@Override
|
|
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
|
|
setSite(site);
|
|
setInput(input);
|
|
|
|
try {
|
|
load();
|
|
} catch (CoreException ex) {
|
|
BasePlugin.getInstance().showError(site.getShell(), ex.getMessage(), ex);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @see org.eclipse.ui.IWorkbenchPart#createPartControl(Composite)
|
|
*/
|
|
@Override
|
|
public void createPartControl(Composite parent) {
|
|
|
|
getSite().setSelectionProvider(this);
|
|
|
|
GridLayout gridLayout = new GridLayout(1, true);
|
|
gridLayout.marginWidth = 0;
|
|
parent.setLayout(gridLayout);
|
|
GridData gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
|
|
gd.horizontalSpan = 1;
|
|
parent.setLayoutData(gd);
|
|
|
|
Composite header = SWTFactory.createComposite(parent, 8, 1, GridData.FILL_HORIZONTAL);
|
|
FillLayout fillLayout = new FillLayout(SWT.HORIZONTAL);
|
|
fillLayout.marginWidth = 10;
|
|
header.setLayout(fillLayout);
|
|
|
|
fileContentSizeField = new TextField(header, Texts.HEX_EDITOR_FILE_CONTENT_SIZE_FIELD_LABEL + LABEL_SUFFIX,
|
|
SWT.READ_ONLY);
|
|
fileContentSizeField.getLabel().setAlignment(SWT.RIGHT);
|
|
|
|
fileContentModeField = new EnumField<HexEditorFileContentMode>(header,
|
|
Texts.HEX_EDITOR_FILE_CONTENT_MODE_FIELD_LABEL + LABEL_SUFFIX, HexEditorFileContentMode.class, null);
|
|
fileContentModeField.getLabel().setAlignment(SWT.RIGHT);
|
|
|
|
messageManager.registerField(fileContentModeField, MessageIds.FILE_CONTENT_MODE);
|
|
fileContentModeField.addSelectionAction(new Action(Actions.FILE_CONTENT_MODE_CHANGED, this));
|
|
|
|
characterSetField = new EnumField<HardwareCharacterSet>(header,
|
|
Texts.HEX_EDITOR_CHARACTER_SET_TYPE_FIELD_LABEL + LABEL_SUFFIX, HardwareCharacterSet.class, null);
|
|
characterSetField.getLabel().setAlignment(SWT.RIGHT);
|
|
messageManager.registerField(characterSetField, MessageIds.CHARACTER_SET);
|
|
characterSetField.addSelectionAction(new Action(Actions.CHARACTER_SET_TYPE_CHANGED, this));
|
|
|
|
bytesPerRowField = new IntegerField(header, Texts.HEX_EDITOR_BYTES_PER_ROW_FIELD_LABEL + LABEL_SUFFIX, null,
|
|
false, 1, SWT.NONE);
|
|
bytesPerRowField.getLabel().setAlignment(SWT.RIGHT);
|
|
messageManager.registerField(characterSetField, MessageIds.BYTES_PER_LINE);
|
|
bytesPerRowField.getControl().addKeyListener(new KeyListener() {
|
|
|
|
@Override
|
|
public void keyReleased(KeyEvent e) {
|
|
if (e.keyCode == '\r') {
|
|
performAction(new Action(Actions.BYTES_PER_ROW_CHANGED, HexEditor.this));
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
public void keyPressed(KeyEvent e) {
|
|
|
|
}
|
|
});
|
|
bytesPerRowField.getControl().addFocusListener(new FocusListener() {
|
|
|
|
@Override
|
|
public void focusLost(FocusEvent e) {
|
|
performAction(new Action(Actions.BYTES_PER_ROW_CHANGED, HexEditor.this));
|
|
|
|
}
|
|
|
|
@Override
|
|
public void focusGained(FocusEvent e) {
|
|
}
|
|
});
|
|
|
|
// SWT.WRAP is very slow, so it's not used.
|
|
textField = new StyledText(parent, SWT.SCROLL_LINE | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY);
|
|
gd = new GridData(GridData.FILL_VERTICAL | GridData.FILL_HORIZONTAL);
|
|
gd.horizontalIndent = 0;
|
|
textField.setLayoutData(gd);
|
|
textField.setIndent(10);
|
|
textField.setLineSpacing(0);
|
|
|
|
// Create a menu manager for the context menu.
|
|
MenuManager manager = new MenuManager(CONTEXT_MENU_ID, CONTEXT_MENU_ID);
|
|
manager.setRemoveAllWhenShown(true);
|
|
|
|
// Create menu and link to the field.
|
|
Menu textContextMenu = manager.createContextMenu(textField);
|
|
textField.setMenu(textContextMenu);
|
|
|
|
getEditorSite().registerContextMenu(CONTEXT_MENU_ID, manager, this, false);
|
|
messageManager.clearMessages();
|
|
dataToUi();
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
@Override
|
|
public <T> T getAdapter(Class<T> adapter) {
|
|
if (adapter != null && IContentOutlinePage.class.equals(adapter)) {
|
|
if (contentOutlinePage == null) {
|
|
|
|
contentOutlinePage = new HexEditorContentOutlinePage(this);
|
|
contentOutlinePage.setInput(parserComponent.getOutlineBlocks());
|
|
}
|
|
|
|
return (T) contentOutlinePage;
|
|
}
|
|
return super.getAdapter(adapter);
|
|
}
|
|
|
|
/**
|
|
* @see org.eclipse.ui.IWorkbenchPart#setFocus()
|
|
*/
|
|
@Override
|
|
public void setFocus() {
|
|
textField.setFocus();
|
|
}
|
|
|
|
private void load() throws CoreException {
|
|
|
|
// Clear fields.
|
|
ioFile = null;
|
|
iFile = null;
|
|
|
|
String fileName = "";
|
|
IEditorInput input = getEditorInput();
|
|
if (input instanceof IFileEditorInput) {
|
|
// Input file found in Eclipse Workspace.
|
|
iFile = ((IFileEditorInput) input).getFile();
|
|
ioFile = iFile.getRawLocation().toFile();
|
|
fileName = iFile.getName();
|
|
} else if (input instanceof IPathEditorInput) {
|
|
// Input file is outside the Eclipse Workspace
|
|
IPathEditorInput pathEditorInput = (IPathEditorInput) input;
|
|
IPath path = pathEditorInput.getPath();
|
|
ioFile = path.toFile();
|
|
fileName = ioFile.getName();
|
|
|
|
} else {
|
|
// Not supported.
|
|
}
|
|
|
|
byte[] fileContent;
|
|
Profiler profiler = new Profiler(this);
|
|
profiler.begin("readBytes", fileName);
|
|
if (ioFile != null) {
|
|
fileContent = FileUtility.readBytes(ioFile, MAX_FILE_SIZE, false);
|
|
} else if (iFile != null) {
|
|
fileContent = FileUtility.readBytes(iFile, MAX_FILE_SIZE, false);
|
|
} else {
|
|
fileContent = new byte[0];
|
|
}
|
|
profiler.end("readBytes");
|
|
|
|
// Set the content, determine the default file content mode and
|
|
// character set.
|
|
parserComponent.setFileContent(fileContent);
|
|
HexEditorFileContentMode defaultFileContentMode = parserComponent.determinePossibleFileContentModes();
|
|
HardwareCharacterSet defaultCharacterSet = defaultFileContentMode.getDefaultCharacterSet();
|
|
parserComponent.setFileContentMode(defaultFileContentMode);
|
|
parserComponent.setCharacterSet(defaultCharacterSet);
|
|
|
|
setPartName(fileName);
|
|
|
|
}
|
|
|
|
public int getBytesPerRow() {
|
|
return parserComponent.getBytesPerRow();
|
|
}
|
|
|
|
@Override
|
|
public void addSelectionChangedListener(ISelectionChangedListener listener) {
|
|
// Nothing.
|
|
}
|
|
|
|
@Override
|
|
public void removeSelectionChangedListener(ISelectionChangedListener listener) {
|
|
// Nothing.
|
|
}
|
|
|
|
@Override
|
|
public HexEditorSelection getSelection() {
|
|
|
|
if (textField == null) {
|
|
return null;
|
|
}
|
|
Point textFieldSelection = textField.getSelection();
|
|
String selectedText = textField.getText().substring(textFieldSelection.x, textFieldSelection.y);
|
|
|
|
if (textFieldSelection.x == textFieldSelection.y) {
|
|
return null;
|
|
}
|
|
|
|
BasePlugin.getInstance().log("HexEditor selectedText=\"{0}\", selection.x={1}, selection.y={2}", new Object[] {
|
|
selectedText, String.valueOf(textFieldSelection.x), String.valueOf(textFieldSelection.y) });
|
|
|
|
lastEditorSelection = parserComponent.getSelection(textFieldSelection.x, textFieldSelection.y);
|
|
|
|
return lastEditorSelection;
|
|
}
|
|
|
|
@Override
|
|
public void setSelection(ISelection selection) {
|
|
// Single range selection?
|
|
if (selection instanceof HexEditorSelection) {
|
|
HexEditorSelection hexEditorSelection = (HexEditorSelection) selection;
|
|
long textStartOffset = parserComponent.getByteTextOffset(hexEditorSelection.getStartOffset());
|
|
long textEndOffset = parserComponent.getByteTextOffset(hexEditorSelection.getEndOffset());
|
|
setSelectionOffsets(textStartOffset, textEndOffset);
|
|
// Range of outline tree objects?
|
|
} else if (selection instanceof IStructuredSelection) {
|
|
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
|
|
|
|
if (structuredSelection.getFirstElement() instanceof HexEditorContentOutlineTreeObject) {
|
|
Iterator<?> i = ((IStructuredSelection) selection).iterator();
|
|
|
|
long textStartOffset = Long.MAX_VALUE;
|
|
long textEndOffset = Long.MIN_VALUE;
|
|
while (i.hasNext()) {
|
|
HexEditorContentOutlineTreeObject treeObject = (HexEditorContentOutlineTreeObject) i.next();
|
|
textStartOffset = Math.min(treeObject.getTextStartOffset(), textStartOffset);
|
|
textEndOffset = Math.max(treeObject.getTextEndOffset(), textEndOffset);
|
|
}
|
|
setSelectionOffsets(textStartOffset, textEndOffset);
|
|
}
|
|
|
|
}
|
|
setFocus();
|
|
}
|
|
|
|
private void setSelectionOffsets(long textStartOffset, long textEndOffset) {
|
|
if (textStartOffset < 0 || textEndOffset > Integer.MAX_VALUE) {
|
|
throw new IllegalArgumentException("Parameter textStartOffset=" + textStartOffset + " is out of range");
|
|
}
|
|
if (textEndOffset < 0 || textEndOffset > Integer.MAX_VALUE) {
|
|
throw new IllegalArgumentException("Parameter textStartOffset=" + textStartOffset + " is out of range");
|
|
}
|
|
try {
|
|
// Mark complete selection area. This also scrolls to
|
|
// the end of the area.
|
|
textField.setSelection(new Point((int) textStartOffset, (int) textEndOffset));
|
|
lastEditorSelection = null;
|
|
|
|
//
|
|
// // But we want to see start of the selection are, so
|
|
// // position explicitly.
|
|
textField.setTopIndex(textField.getContent().getLineAtOffset((int) textStartOffset));
|
|
} catch (IllegalArgumentException x) {
|
|
// Ignore
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the file path for saving the current selection. Called by
|
|
* {@link HexEditorSaveSelectionAsCommandHandler }.
|
|
*
|
|
* @return The file path, not <code>null</code>.
|
|
*/
|
|
public String getSelectionSaveFilePath() {
|
|
String result = "Selection";
|
|
String extension = ".bin";
|
|
if (parserComponent.getFileContentMode().equals(HexEditorFileContentMode.ATARI_DISK_IMAGE_K_FILE)) {
|
|
extension = ".xex";
|
|
}
|
|
|
|
if (ioFile != null) {
|
|
result = ioFile.getAbsolutePath();
|
|
int index = result.lastIndexOf('.');
|
|
if (index >= 0) {
|
|
result = result.substring(0, index);
|
|
}
|
|
}
|
|
|
|
result += extension;
|
|
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public boolean isDirty() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void doSave(IProgressMonitor monitor) {
|
|
// Nothing.
|
|
|
|
}
|
|
|
|
@Override
|
|
public boolean isSaveAsAllowed() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void doSaveAs() {
|
|
// Nothing.
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public MessageManager getMessageManager() {
|
|
return messageManager;
|
|
}
|
|
|
|
private void dataFromUi() {
|
|
messageManager.clearMessages();
|
|
parserComponent.setFileContentMode(fileContentModeField.getValue());
|
|
parserComponent.setCharacterSet(characterSetField.getValue());
|
|
int bytesPerRow = bytesPerRowField.getValue();
|
|
if (bytesPerRow < 1) {
|
|
bytesPerRow = 16;
|
|
} else if (bytesPerRow > 256) {
|
|
bytesPerRow = 256;
|
|
}
|
|
parserComponent.setBytesPerRow(bytesPerRow);
|
|
}
|
|
|
|
private void dataToUi() {
|
|
|
|
// File content size.
|
|
FileContent fileContent = parserComponent.getFileContent();
|
|
long length = fileContent.getLength();
|
|
String text = TextUtility.format(Texts.HEX_EDITOR_FILE_CONTENT_SIZE_FIELD_TEXT,
|
|
HexUtility.getLongValueHexString(length), NumberUtility.getLongValueDecimalString(length));
|
|
fileContentSizeField.setValue(text);
|
|
|
|
// File content mode.
|
|
fileContentModeField.setValue(parserComponent.getFileContentMode());
|
|
|
|
// Character set.
|
|
HardwareCharacterSet characterSet = parserComponent.getCharacterSet();
|
|
characterSetField.setValue(characterSet);
|
|
if (!textField.getFont().equals(characterSet.getFont())) {
|
|
textField.setFont(characterSet.getFont());
|
|
}
|
|
|
|
// Bytes per Row
|
|
bytesPerRowField.setValue(parserComponent.getBytesPerRow());
|
|
|
|
if (parserComponent.isParsingFileContentRequired()) {
|
|
StyledString styledString = parserComponent.parseFileContent();
|
|
textField.setText(styledString.getString());
|
|
lastEditorSelection = null;
|
|
textField.setStyleRanges(styledString.getStyleRanges());
|
|
|
|
if (contentOutlinePage != null) {
|
|
contentOutlinePage.setInput(parserComponent.getOutlineBlocks());
|
|
}
|
|
}
|
|
|
|
messageManager.displayMessages();
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public void performAction(Action action) {
|
|
try {
|
|
|
|
ISelection oldSelection = null;
|
|
dataFromUi();
|
|
|
|
switch (action.getId()) {
|
|
case Actions.FILE_CONTENT_MODE_CHANGED:
|
|
case Actions.CHARACTER_SET_TYPE_CHANGED:
|
|
case Actions.BYTES_PER_ROW_CHANGED:
|
|
oldSelection = getSelection();
|
|
break;
|
|
}
|
|
|
|
dataToUi();
|
|
if (oldSelection != null) {
|
|
setSelection(oldSelection);
|
|
}
|
|
} catch (Exception ex) {
|
|
BasePlugin.getInstance().showError(getSite().getShell(), "Error in update()", ex);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Called by {@link HexEditorClipboardCommandHandler}.
|
|
*
|
|
* @param bytes The byte array to be pasted, may be empty, not
|
|
* <code>null</code>.
|
|
*
|
|
* TODO Hex paste is not working yet
|
|
*/
|
|
final void pasteFromClipboard(byte[] bytes) {
|
|
if (bytes == null) {
|
|
throw new IllegalArgumentException("Parameter 'bytes' must not be null.");
|
|
}
|
|
HexEditorSelection selection = getSelection();
|
|
// byte[] newFileContent;
|
|
//
|
|
// // If there is no end offset, we insert the new bytes.
|
|
// if (selection.getEndOffset() !=
|
|
// HexEditorParserComponent.UNDEFINED_OFFSET) {
|
|
// int selectionStartOffset = (int) selection.getStartOffset();
|
|
// int selectionEndOffset = (int) selection.getEndOffset();
|
|
//
|
|
// int selectionLength = selectionEndOffset - selectionStartOffset + 1;
|
|
// int newFileContentLength = parserComponent.getFileContent().length -
|
|
// selectionLength + bytes.length;
|
|
// newFileContent = new byte[newFileContentLength];
|
|
// System.arraycopy(parserComponent.getFileContent(), 0, newFileContent,
|
|
// 0, selectionStartOffset);
|
|
// System.arraycopy(bytes, 0, newFileContent, selectionStartOffset,
|
|
// bytes.length);
|
|
// int length = parserComponent.getFileContent().length -
|
|
// selectionEndOffset - 1;
|
|
// if (length > 0) {
|
|
// // TODO Hex paste is not working yet
|
|
// System.arraycopy(parserComponent.getFileContent(),
|
|
// selectionEndOffset, newFileContent,
|
|
// selectionStartOffset + bytes.length, length);
|
|
// }
|
|
// messageManager.sendMessage(0, IStatus.OK,
|
|
// "${0} ({1}) bytes pasted from clipboard to replace ${2} ({3}) bytes
|
|
// ",
|
|
// HexUtility.getLongValueHexString(bytes.length),
|
|
// NumberUtility.getLongValueDecimalString(bytes.length),
|
|
// HexUtility.getLongValueHexString(selectionLength),
|
|
// NumberUtility.getLongValueDecimalString(selectionLength));
|
|
// } else {
|
|
// // If there is an end offset, we replace the selection with the new
|
|
// // bytes.
|
|
// newFileContent = parserComponent.getFileContent();
|
|
// messageManager.sendMessage(0, IStatus.OK, "${0} ({1}) bytes inserted
|
|
// from clipboard",
|
|
// HexUtility.getLongValueHexString(bytes.length),
|
|
// NumberUtility.getLongValueDecimalString(bytes.length));
|
|
// }
|
|
//
|
|
// parserComponent.setFileContent(newFileContent);
|
|
dataToUi();
|
|
|
|
}
|
|
|
|
}
|