Package com.subgraph.vega.ui.hexeditor

Source Code of com.subgraph.vega.ui.hexeditor.HexEditControl

/*******************************************************************************
* Copyright (c) 2011 Subgraph.
* 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:
*     Subgraph - initial API and implementation
******************************************************************************/
package com.subgraph.vega.ui.hexeditor;

import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.CellNavigationStrategy;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationListener;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.ColumnViewerEditorDeactivationEvent;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TableViewerEditor;
import org.eclipse.jface.viewers.TableViewerFocusCellManager;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

public class HexEditControl extends Composite {
  private final static int WORD_SIZE = 4;
  private final static int MINIMUM_DATA_COLUMNS = 4;
  private final HexEditFonts fonts;
  private TableViewer tableViewer;
  private HexEditModel model;
  private int currentDataColumnCount;
  private boolean editable = true;
  private volatile boolean enablePreserveSelection = true;
  public HexEditControl(Composite parent) {
    super(parent, SWT.NONE);
    this.fonts = new HexEditFonts(this);
    currentDataColumnCount = calculateDataColumnCount(getClientArea().width);
    tableViewer = createTableViewer();
    tableViewer.setContentProvider(new HexEditContentProvider(tableViewer));
    createColumns(currentDataColumnCount);
   
    addControlListener(createControlListener());
  }
 
  private TableViewer createTableViewer() {
    final TableViewer tv = new TableViewer(this, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.VIRTUAL) {
      @Override
      protected void preservingSelection(Runnable updateCode) {
        if(enablePreserveSelection)
          super.preservingSelection(updateCode);
      }
    };
   
    tv.getTable().setHeaderVisible(true)
    tv.setUseHashlookup(true);
    if(editable)
      addEditorSupport(tv);
    return tv;
  }
  /*
   * Q: teh fuck is this?
   * A: http://bingjava.appspot.com/snippet.jsp?id=2213
   */
  private void addEditorSupport(TableViewer tv) {
    final CellNavigationStrategy cellNavigation = createCellNavigationStrategy(tv);
    final TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(tv, new FocusCellOwnerDrawHighlighter(tv), cellNavigation);
    final ColumnViewerEditorActivationStrategy activationStrategy = createEditorActivationStrategy(tv);
    TableViewerEditor.create(tv, focusCellManager, activationStrategy,
        ColumnViewerEditor.TABBING_HORIZONTAL
        | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR
        | ColumnViewerEditor.TABBING_VERTICAL
        | ColumnViewerEditor.KEYBOARD_ACTIVATION);
    tv.getColumnViewerEditor().addEditorActivationListener(createEditorActivationListener(tv));
  }
  private CellNavigationStrategy createCellNavigationStrategy(TableViewer tv) {
    final Table t = tv.getTable();
    return new CellNavigationStrategy() {
      @Override
      public ViewerCell findSelectedCell(ColumnViewer viewer,
          ViewerCell currentSelectedCell, Event event) {
        final ViewerCell cell = super.findSelectedCell(viewer, currentSelectedCell, event);
        if(cell != null) {
          t.showColumn(t.getColumn(cell.getColumnIndex()));
        }
        return cell;
      }
    };
  }
 
  private ColumnViewerEditorActivationStrategy createEditorActivationStrategy(TableViewer tv) {
    return new ColumnViewerEditorActivationStrategy(tv) {
      protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
        return  event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL
        ||  event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION
        || (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == SWT.CR);
      }
    };
  }
  private ColumnViewerEditorActivationListener createEditorActivationListener(TableViewer tv) {
    final Table t = tv.getTable();
    return new ColumnViewerEditorActivationListener() {
     
      @Override
      public void beforeEditorDeactivated(
          ColumnViewerEditorDeactivationEvent event) {
      }
     
      @Override
      public void beforeEditorActivated(ColumnViewerEditorActivationEvent event) {   
        ViewerCell cell = (ViewerCell) event.getSource();
        t.showColumn(t.getColumn(cell.getColumnIndex()));
      }
     
      @Override
      public void afterEditorDeactivated(ColumnViewerEditorDeactivationEvent event) {       
      }
     
      @Override
      public void afterEditorActivated(ColumnViewerEditorActivationEvent event) {
      }
    };
  }
 
  public void setInput(byte[] binaryData) {
    if(currentDataColumnCount == 0) {
      model = new HexEditModel(binaryData);
    } else {
      model = new HexEditModel(binaryData, currentDataColumnCount);
    }
    changeModel(model);
  }
 
  public boolean isContentDirty() {
    if(model != null) {
      return model.isDirty();
    } else {
      return false;
    }
  }
 
  public byte[] getContent() {
    return model.getContent();
  }
 
  private void changeModel(final HexEditModel model) {
    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=200214
    enablePreserveSelection = false;
    tableViewer.setInput(model);
    enablePreserveSelection = true;   
  }

  private void createColumns(int dataColumnCount) {
    tableViewer.getTable().dispose();
    tableViewer = createTableViewer();
    tableViewer.setContentProvider(new HexEditContentProvider(tableViewer));
    final TableColumnLayout layout = new TableColumnLayout();
    createOffsetColumn(layout);
    for(int i = 0; i < dataColumnCount; i++)
      createDataColumn(layout, i);
    createAsciiColumn(layout);
    setLayout(layout);
    tableViewer.setLabelProvider(new HexEditLabelProvider(fonts));
  }
 
  private void createOffsetColumn(TableColumnLayout layout) {
    final TableColumn c = createColumn("Offset", SWT.CENTER);
    c.setAlignment(SWT.RIGHT);
    layout.setColumnData(c, new ColumnPixelData(fonts.getOffsetColumnWidth(), false, false));
  }
 
  private void createAsciiColumn(TableColumnLayout layout) {
    final TableColumn c = createColumn("", SWT.CENTER);
    layout.setColumnData(c, new ColumnWeightData(100));
  }
 
  private void createDataColumn(TableColumnLayout layout, int index) {
    final EditingSupport editor = (editable) ? (new HexEditTableEditor(tableViewer, index)) : (null);
    final TableColumn c = createColumn(String.format("%02X", index), SWT.CENTER, editor);
    layout.setColumnData(c, new ColumnPixelData(fonts.getDataColumnWidth(), false, false));
  }
 
  private TableColumn createColumn(String headerText, int align) {
    return createColumn(headerText, align, null);
  }

  private TableColumn createColumn(String headerText, int align, EditingSupport editor) {
    final TableViewerColumn tvc = new TableViewerColumn(tableViewer, align);
    final TableColumn tc = tvc.getColumn();
    tc.setMoveable(false);
    tc.setResizable(false);
    tc.setText(headerText);
    if(editor != null)
      tvc.setEditingSupport(editor);
    return tc;
  }
 
  private ControlListener createControlListener() {
    return new ControlAdapter() {
      @Override
      public void controlResized(ControlEvent e) {
        doResize();
      }
    };
  }

  private void doResize() {
    final int width = getClientArea().width;   
    final int cc = calculateDataColumnCount(width);
    if(cc != currentDataColumnCount) {
      changeModel(null);
      createColumns(cc);
      if(model != null) {
        // Remembering old offset does not work on Linux.  Maybe because of these bugs:
        //
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=74739
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=202392
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=295666
        final HexEditModel newModel = model.getModelForRowLength(cc);
        final int topIndex = tableViewer.getTable().getTopIndex();
        final int topOffset = model.getOffsetForLine(topIndex);
        final int newTopIndex = newModel.getLineForOffset(topOffset);
        changeModel(newModel);
        model = newModel;       
        if(newTopIndex != 0) {
          tableViewer.getTable().setTopIndex(newTopIndex);
        }   
      } else {
        changeModel(model);
      }
      currentDataColumnCount = cc;
    }
  }
 
 
  private int calculateDataColumnCount(int pixelWidth) {
    /*
     * w = width
     * o = offsetColumnWidth
     * d = dataColumnWidth
     * a = asciiColumnWordWidth
     * n = words
     *
     * w = o + 4nd + na
     * w - o = n(4d + a)
     * n = (w - o) / (4d + a)
     */
   
    int space = (pixelWidth - fonts.getOffsetColumnWidth()) - 30;
    int perWord = WORD_SIZE * fonts.getDataColumnWidth() + fonts.getAsciiColumnWordWidth();
    int words = space / perWord;
    int columns = words * WORD_SIZE;
    return (columns < MINIMUM_DATA_COLUMNS) ? (MINIMUM_DATA_COLUMNS) : (columns);
  }
}
TOP

Related Classes of com.subgraph.vega.ui.hexeditor.HexEditControl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.