Fixed a very stupid bug in InstructionView#highlight
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / tables / mi / InstructionView.java
1 package net.mograsim.plugin.tables.mi;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.FileReader;
6 import java.io.IOException;
7
8 import org.eclipse.core.runtime.IProgressMonitor;
9 import org.eclipse.swt.SWT;
10 import org.eclipse.swt.layout.GridData;
11 import org.eclipse.swt.layout.GridLayout;
12 import org.eclipse.swt.widgets.Button;
13 import org.eclipse.swt.widgets.Composite;
14 import org.eclipse.swt.widgets.Display;
15 import org.eclipse.swt.widgets.FileDialog;
16 import org.eclipse.ui.IEditorInput;
17 import org.eclipse.ui.IEditorSite;
18 import org.eclipse.ui.IPathEditorInput;
19 import org.eclipse.ui.PartInitException;
20 import org.eclipse.ui.part.EditorPart;
21
22 import net.mograsim.machine.Memory.MemoryCellModifiedListener;
23 import net.mograsim.machine.mi.MicroInstructionMemory;
24 import net.mograsim.machine.mi.MicroInstructionMemory.ActiveMicroInstructionChangedListener;
25 import net.mograsim.machine.mi.MicroInstructionMemoryParseException;
26 import net.mograsim.machine.mi.MicroInstructionMemoryParser;
27 import net.mograsim.plugin.MachineContext;
28 import net.mograsim.plugin.tables.DisplaySettings;
29 import net.mograsim.plugin.tables.LazyTableViewer;
30 import net.mograsim.plugin.tables.RadixSelector;
31
32 public class InstructionView extends EditorPart implements MemoryCellModifiedListener, ActiveMicroInstructionChangedListener
33 {
34         private InstructionTableContentProvider provider;
35         private int highlighted = 0;
36         private boolean dirty = false;
37         private String machineName;
38         private MicroInstructionMemory memory;
39         private InstructionTable table;
40
41         @SuppressWarnings("unused")
42         @Override
43         public void createPartControl(Composite parent)
44         {
45                 provider = new InstructionTableLazyContentProvider();
46                 GridLayout layout = new GridLayout(3, false);
47                 parent.setLayout(layout);
48
49                 DisplaySettings displaySettings = new DisplaySettings();
50                 new RadixSelector(parent, displaySettings);
51
52                 addActivationButton(parent);
53
54                 table = new InstructionTable(parent, displaySettings);
55                 table.setContentProvider(provider);
56                 table.bindMicroInstructionMemory(memory);
57
58                 GridData viewerData = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
59                 viewerData.horizontalSpan = 3;
60                 table.getTableViewer().getTable().setLayoutData(viewerData);
61         }
62
63         public void highlight(int index)
64         {
65                 Display.getDefault().asyncExec(() ->
66                 {
67                         LazyTableViewer viewer = table.getTableViewer();
68                         viewer.highlightRow(highlighted, false);
69                         highlighted = index;
70                         viewer.highlightRow(index, true);
71                         viewer.getTable().showItem(viewer.getTable().getItem(Math.min((int) memory.getDefinition().getMaximalAddress(), index + 2)));
72                         viewer.getTable().showItem(viewer.getTable().getItem(index));
73                 });
74         }
75
76         private void addActivationButton(Composite parent)
77         {
78                 Button activationButton = new Button(parent, SWT.PUSH);
79                 activationButton.setText("Set Active");
80                 activationButton.addListener(SWT.Selection,
81                                 e -> MachineContext.getInstance().getMachine().getMicroInstructionMemory().bind(memory));
82         }
83
84         public void bindMicroInstructionMemory(MicroInstructionMemory memory)
85         {
86                 this.memory = memory;
87                 this.memory.registerCellModifiedListener(this);
88                 this.memory.registerActiveMicroInstructionChangedListener(this);
89                 if (table != null)
90                         table.bindMicroInstructionMemory(memory);
91         }
92
93         private void open(String file)
94         {
95                 try (BufferedReader bf = new BufferedReader(new FileReader(file)))
96                 {
97                         machineName = bf.readLine();
98                         bindMicroInstructionMemory(MicroInstructionMemoryParser.parseMemory(machineName, bf));
99                 }
100                 catch (IOException | MicroInstructionMemoryParseException e)
101                 {
102                         e.printStackTrace();
103                 }
104         }
105
106         private void save(String file)
107         {
108                 if (memory == null)
109                 {
110                         System.err.println("Failed to write MicroprogrammingMemory to File. No MicroprogrammingMemory assigned.");
111                         return;
112                 }
113                 try
114                 {
115                         MicroInstructionMemoryParser.write(memory, machineName, file);
116                 }
117                 catch (IOException e)
118                 {
119                         e.printStackTrace();
120                 }
121         }
122
123         @Override
124         public void setFocus()
125         {
126                 table.getTableViewer().getControl().setFocus();
127         }
128
129         @Override
130         public void doSave(IProgressMonitor progressMonitor)
131         {
132                 IEditorInput input = getEditorInput();
133                 if (input instanceof IPathEditorInput)
134                 {
135                         IPathEditorInput pathInput = (IPathEditorInput) input;
136                         save(pathInput.getPath().toOSString());
137                         setDirty(false);
138                 }
139         }
140
141         @Override
142         public void doSaveAs()
143         {
144                 openSaveAsDialog();
145         }
146
147         private void openSaveAsDialog()
148         {
149                 FileDialog d = new FileDialog(table.getTableViewer().getTable().getShell(), SWT.SAVE);
150                 d.open();
151                 String filename = d.getFileName();
152                 if (!filename.equals(""))
153                 {
154                         save(d.getFilterPath() + File.separator + filename);
155                         setDirty(false);
156                 }
157         }
158
159         @Override
160         public void init(IEditorSite site, IEditorInput input) throws PartInitException
161         {
162                 setSite(site);
163                 setInput(input);
164                 if (input instanceof IPathEditorInput)
165                 {
166                         IPathEditorInput pathInput = (IPathEditorInput) input;
167                         setPartName(pathInput.getName());
168                         open(pathInput.getPath().toOSString());
169                 }
170         }
171
172         @Override
173         public boolean isDirty()
174         {
175                 return dirty;
176         }
177
178         @Override
179         public boolean isSaveAsAllowed()
180         {
181                 return true;
182         }
183
184         @Override
185         public void update(long address)
186         {
187                 setDirty(true);
188                 table.refresh();
189         }
190
191         private void setDirty(boolean value)
192         {
193                 dirty = value;
194                 firePropertyChange(PROP_DIRTY);
195         }
196
197         @Override
198         public void activeMicroInstructionChanged(long address)
199         {
200                 highlight((int) (address - memory.getDefinition().getMinimalAddress()));
201         }
202 }