1 package net.mograsim.plugin.editors;
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.math.BigInteger;
7 import org.eclipse.core.resources.IFile;
8 import org.eclipse.core.runtime.CoreException;
9 import org.eclipse.core.runtime.IProgressMonitor;
10 import org.eclipse.jface.util.SafeRunnable;
11 import org.eclipse.jface.viewers.TableViewerColumn;
12 import org.eclipse.swt.SWT;
13 import org.eclipse.swt.layout.GridData;
14 import org.eclipse.swt.layout.GridLayout;
15 import org.eclipse.swt.widgets.Button;
16 import org.eclipse.swt.widgets.Composite;
17 import org.eclipse.swt.widgets.Label;
18 import org.eclipse.swt.widgets.Table;
19 import org.eclipse.swt.widgets.TableColumn;
20 import org.eclipse.swt.widgets.Text;
21 import org.eclipse.ui.IEditorInput;
22 import org.eclipse.ui.IEditorSite;
23 import org.eclipse.ui.IFileEditorInput;
24 import org.eclipse.ui.PartInitException;
25 import org.eclipse.ui.part.EditorPart;
27 import net.mograsim.machine.MainMemory;
28 import net.mograsim.machine.MainMemoryDefinition;
29 import net.mograsim.machine.Memory.MemoryCellModifiedListener;
30 import net.mograsim.machine.mi.MicroInstructionMemoryParseException;
31 import net.mograsim.machine.standard.memory.MainMemoryParser;
32 import net.mograsim.plugin.asm.AsmNumberUtil;
33 import net.mograsim.plugin.nature.MachineContext;
34 import net.mograsim.plugin.nature.ProjectMachineContext;
35 import net.mograsim.plugin.tables.AddressLabelProvider;
36 import net.mograsim.plugin.tables.DisplaySettings;
37 import net.mograsim.plugin.tables.LazyTableViewer;
38 import net.mograsim.plugin.tables.NumberColumnLabelProvider;
39 import net.mograsim.plugin.tables.RadixSelector;
40 import net.mograsim.plugin.tables.memory.MemoryCellEditingSupport;
41 import net.mograsim.plugin.tables.memory.MemoryTableContentProvider;
42 import net.mograsim.plugin.tables.memory.MemoryTableRow;
43 import net.mograsim.plugin.tables.memory.NumberVerifyListener;
45 public class MemoryEditor extends EditorPart
47 private MachineContext context;
49 private MainMemory memory;
51 private LazyTableViewer viewer;
52 private MemoryTableContentProvider provider;
53 private DisplaySettings displaySettings;
55 private boolean dirty;
57 private final MemoryCellModifiedListener memListener;
61 memListener = this::cellModified;
65 public void createPartControl(Composite parent)
67 provider = new MemoryTableContentProvider();
68 displaySettings = new DisplaySettings();
70 parent.setLayout(new GridLayout(7, false));
75 displaySettings.addObserver(() -> viewer.refresh());
78 @SuppressWarnings("unused") // RadixSelector and exceptions
79 private void createHeader(Composite parent)
81 Label fromLabel = new Label(parent, SWT.NONE);
82 fromLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
83 fromLabel.setText("Address: ");
85 Text fromText = new Text(parent, SWT.BORDER);
86 fromText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
87 NumberVerifyListener vl = new NumberVerifyListener();
88 fromText.addVerifyListener(vl);
89 fromText.setText("0");
90 fromText.addModifyListener(e ->
94 provider.setLowerBound(AsmNumberUtil.valueOf(fromText.getText()).longValue());
97 catch (NumberFormatException x)
102 Label amountLabel = new Label(parent, SWT.NONE);
103 amountLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
104 amountLabel.setText("Number of cells: ");
105 Text amountText = new Text(parent, SWT.BORDER);
106 amountText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
107 amountText.addVerifyListener(vl);
108 amountText.setText("0");
109 amountText.addModifyListener(e ->
113 provider.setAmount(AsmNumberUtil.valueOf(amountText.getText()).intValue());
116 catch (NumberFormatException x)
118 // Nothing to do here
121 new RadixSelector(parent, displaySettings);
123 addActivationButton(parent);
126 private void addActivationButton(Composite parent)
128 Button activationButton = new Button(parent, SWT.PUSH);
129 activationButton.setText("Set Active");
130 activationButton.addListener(SWT.Selection, e -> context.getActiveMachine().ifPresent(m -> m.getMainMemory().bind(memory)));
133 private void createViewer(Composite parent)
135 viewer = new LazyTableViewer(parent, SWT.FULL_SELECTION | SWT.BORDER | SWT.VIRTUAL);
137 Table table = viewer.getTable();
138 table.setHeaderVisible(true);
139 table.setLinesVisible(true);
140 viewer.setUseHashlookup(true);
141 viewer.setContentProvider(provider);
142 getSite().setSelectionProvider(viewer);// TODO what does this?
143 viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 7, 1));
145 viewer.setInput(memory);
148 private void createColumns()
150 TableViewerColumn addrCol = createTableViewerColumn("Address", 100);
151 addrCol.setLabelProvider(new AddressLabelProvider());
153 TableViewerColumn dataCol = createTableViewerColumn("Data", 100);
154 dataCol.setLabelProvider(new NumberColumnLabelProvider(displaySettings)
157 public BigInteger getAsBigInteger(Object element)
159 MemoryTableRow row = (MemoryTableRow) element;
160 return row.getMemory().getCellAsBigInteger(row.address);
164 public int getBitLength(Object element)
166 return ((MemoryTableRow) element).getMemory().getDefinition().getCellWidth();
169 dataCol.setEditingSupport(new MemoryCellEditingSupport(viewer, displaySettings));
172 private TableViewerColumn createTableViewerColumn(String title, int width)
174 TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
175 TableColumn column = viewerColumn.getColumn();
176 column.setText(title);
177 column.setWidth(width);
178 column.setResizable(true);
179 column.setMoveable(false);
184 public void init(IEditorSite site, IEditorInput input) throws PartInitException
186 if (input instanceof IFileEditorInput)
188 IFileEditorInput fileInput = (IFileEditorInput) input;
189 context = ProjectMachineContext.getMachineContextOf(fileInput.getFile().getProject());
190 context.activateMachine();
192 setPartName(fileInput.getName());
195 open(fileInput.getFile());
199 throw new PartInitException("Failed to read input!", e);
202 throw new IllegalArgumentException("MemoryEditor can only be used with Files");
209 public void doSave(IProgressMonitor monitor)
211 IEditorInput input = getEditorInput();
212 if (input instanceof IFileEditorInput)
213 SafeRunnable.getRunner().run(() -> save(((IFileEditorInput) input).getFile(), monitor));
216 private void save(IFile file, IProgressMonitor monitor) throws CoreException, IOException
220 throw new MicroInstructionMemoryParseException("Failed to write MainMemory to File. No MainMemory assigned.");
222 try (InputStream toWrite = MainMemoryParser.write(memory))
224 file.setContents(toWrite, 0, monitor);
229 private void open(IFile file) throws IOException, CoreException
231 MainMemoryDefinition memDef = context.getMachineDefinition()
232 .orElseThrow(() -> new MicroInstructionMemoryParseException("No MachineDefinition assigned!")).getMainMemoryDefinition();
233 memory = MainMemoryParser.parseMemory(memDef, file.getContents());
234 memory.registerCellModifiedListener(memListener);
236 viewer.setInput(memory);
239 private void cellModified(@SuppressWarnings("unused") long address)
244 private void setDirty(boolean newDirty)
247 firePropertyChange(PROP_DIRTY);
251 public void doSaveAs()
253 throw new UnsupportedOperationException();
257 public boolean isDirty()
263 public boolean isSaveAsAllowed()
269 public void setFocus()
271 viewer.getTable().setFocus();
275 public void dispose()
278 memory.deregisterCellModifiedListener(memListener);