MPM file gets loaded when MainMachineLaunchConfigTab is created
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / launch / MainMachineLaunchConfigTab.java
1 package net.mograsim.plugin.launch;
2
3 import java.util.Arrays;
4 import java.util.HashSet;
5 import java.util.Set;
6 import java.util.function.Supplier;
7
8 import org.eclipse.core.resources.IProject;
9 import org.eclipse.core.resources.IResource;
10 import org.eclipse.core.resources.IWorkspace;
11 import org.eclipse.core.resources.ResourcesPlugin;
12 import org.eclipse.core.runtime.CoreException;
13 import org.eclipse.core.runtime.IStatus;
14 import org.eclipse.debug.core.ILaunchConfiguration;
15 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
16 import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
17 import org.eclipse.jface.dialogs.IDialogConstants;
18 import org.eclipse.jface.layout.PixelConverter;
19 import org.eclipse.jface.resource.ImageDescriptor;
20 import org.eclipse.jface.window.Window;
21 import org.eclipse.osgi.util.NLS;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.graphics.Point;
24 import org.eclipse.swt.layout.FillLayout;
25 import org.eclipse.swt.layout.GridData;
26 import org.eclipse.swt.layout.GridLayout;
27 import org.eclipse.swt.widgets.Button;
28 import org.eclipse.swt.widgets.Composite;
29 import org.eclipse.swt.widgets.Control;
30 import org.eclipse.swt.widgets.Group;
31 import org.eclipse.swt.widgets.Text;
32 import org.eclipse.ui.dialogs.ElementListSelectionDialog;
33 import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
34 import org.eclipse.ui.model.WorkbenchContentProvider;
35 import org.eclipse.ui.model.WorkbenchLabelProvider;
36
37 import net.mograsim.plugin.nature.MograsimNature;
38 import net.mograsim.plugin.util.FileExtensionViewerFilter;
39 import net.mograsim.plugin.util.ImageDescriptorWithMargins;
40
41 //a big part of this class is stolen from org.eclipse.jdt.debug.ui
42 public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab
43 {
44         private Text projSelText;
45         private Text mpmFileSelText;
46
47         @Override
48         public void createControl(Composite parent)
49         {
50                 parent.setLayout(new FillLayout());
51                 Composite innerParent = new Composite(parent, SWT.NONE);
52                 setControl(innerParent);
53
54                 innerParent.setLayout(new GridLayout());
55
56                 this.projSelText = createResourceSelectorGroup(innerParent, "&Project:", this::chooseMograsimProject);
57
58                 this.mpmFileSelText = createResourceSelectorGroup(innerParent, "&MPM:", this::chooseMPMFile);
59
60                 // TODO RAM selector
61         }
62
63         private Text createResourceSelectorGroup(Composite innerParent, String groupName, Supplier<String> chooser)
64         {
65                 Group group = new Group(innerParent, SWT.NONE);
66                 group.setLayout(new GridLayout(2, false));
67                 group.setText(groupName);
68                 group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
69
70                 Text text = new Text(group, SWT.BORDER);
71                 text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
72                 text.addModifyListener(e -> updateLaunchConfigurationDialog());
73
74                 Button browseButton = new Button(group, SWT.PUSH);
75                 GridData projSelButtonData = new GridData();
76                 projSelButtonData.widthHint = calculateWidthHint(browseButton);
77                 projSelButtonData.horizontalAlignment = SWT.FILL;
78                 browseButton.setLayoutData(projSelButtonData);
79                 browseButton.setText("&Browse...");
80                 browseButton.addListener(SWT.Selection, e ->
81                 {
82                         String chosen = chooser.get();
83                         if (chosen != null)
84                                 text.setText(chosen);
85                 });
86                 return text;
87         }
88
89         private static int calculateWidthHint(Control c)
90         {
91                 int wHint = new PixelConverter(c).convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
92                 return Math.max(wHint, c.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
93         }
94
95         private String chooseMograsimProject()
96         {
97                 WorkbenchLabelProvider renderer = new WorkbenchLabelProvider()
98                 {
99                         @Override
100                         protected ImageDescriptor decorateImage(ImageDescriptor input, Object element)
101                         {
102                                 return new ImageDescriptorWithMargins(input, new Point(22, 16));
103                         }
104                 };
105                 ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), renderer);
106                 dialog.setTitle("Project Selection");
107                 dialog.setMessage("Select a Mograsim project");
108                 dialog.setElements(filterOpenMograsimProjects(ResourcesPlugin.getWorkspace().getRoot().getProjects()));
109                 if (dialog.open() == Window.OK)
110                         return ((IProject) dialog.getFirstResult()).getName();
111                 return null;
112         }
113
114         private String chooseMPMFile()
115         {
116                 WorkbenchLabelProvider renderer = new WorkbenchLabelProvider()
117                 {
118                         @Override
119                         protected ImageDescriptor decorateImage(ImageDescriptor input, Object element)
120                         {
121                                 return new ImageDescriptorWithMargins(input, new Point(22, 16));
122                         }
123                 };
124                 ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), renderer, new WorkbenchContentProvider());
125                 dialog.setInput(getSelectedProject());
126                 dialog.addFilter(new FileExtensionViewerFilter("mpm"));
127
128                 if (dialog.open() == Window.OK)
129                         return ((IResource) dialog.getResult()[0]).getProjectRelativePath().toPortableString();
130                 return null;
131         }
132
133         private IProject getSelectedProject()
134         {
135                 String projName = projSelText.getText().trim();
136                 IWorkspace workspace = ResourcesPlugin.getWorkspace();
137                 if (workspace.validateName(projName, IResource.PROJECT).isOK())
138                         return workspace.getRoot().getProject(projName);
139                 return null;
140         }
141
142         private static IProject[] filterOpenMograsimProjects(IProject[] projects)
143         {
144                 return Arrays.stream(projects).filter(p ->
145                 {
146                         try
147                         {
148                                 return p.isAccessible() && p.hasNature(MograsimNature.NATURE_ID);
149                         }
150                         catch (CoreException e)
151                         {
152                                 throw new RuntimeException(e);
153                         }
154                 }).toArray(IProject[]::new);
155         }
156
157         @Override
158         public void setDefaults(ILaunchConfigurationWorkingCopy configuration)
159         {
160                 // TODO don't let the user have to specify everything
161         }
162
163         @Override
164         public void initializeFrom(ILaunchConfiguration configuration)
165         {
166                 projSelText.setText(getStringAttribSafe(configuration, MachineLaunchConfigType.PROJECT_ATTR, ""));
167                 mpmFileSelText.setText(getStringAttribSafe(configuration, MachineLaunchConfigType.MPM_FILE_ATTR, ""));
168         }
169
170         private String getStringAttribSafe(ILaunchConfiguration configuration, String attrib, String defaultValue)
171         {
172                 try
173                 {
174                         return configuration.getAttribute(attrib, defaultValue);
175                 }
176                 catch (CoreException e)
177                 {
178                         setErrorMessage(e.getStatus().getMessage());
179                 }
180                 return defaultValue;
181         }
182
183         @Override
184         public void performApply(ILaunchConfigurationWorkingCopy configuration)
185         {
186                 String projName = projSelText.getText().trim();
187                 String mpmFileName = mpmFileSelText.getText().trim();
188
189                 Set<IResource> associatedResources = new HashSet<>();
190                 IWorkspace workspace = ResourcesPlugin.getWorkspace();
191                 if (workspace.validateName(projName, IResource.PROJECT).isOK())
192                 {
193                         IProject project = workspace.getRoot().getProject(projName);
194                         try
195                         {
196                                 if (project != null && project.isAccessible() && project.hasNature(MograsimNature.NATURE_ID))
197                                 {
198                                         IResource mpmFile = project.findMember(mpmFileName);
199                                         if (mpmFile != null && mpmFile.exists() && mpmFile.getType() == IResource.FILE)
200                                                 associatedResources.add(mpmFile);
201                                         else
202                                                 associatedResources.add(project);
203                                 }
204                         }
205                         catch (CoreException e)
206                         {
207                                 setErrorMessage(e.getStatus().getMessage());
208                         }
209                 }
210                 configuration.setMappedResources(associatedResources.toArray(IResource[]::new));
211                 configuration.setAttribute(MachineLaunchConfigType.PROJECT_ATTR, projName);
212                 configuration.setAttribute(MachineLaunchConfigType.MPM_FILE_ATTR, mpmFileName);
213         }
214
215         @Override
216         public boolean isValid(ILaunchConfiguration launchConfig)
217         {
218                 setErrorMessage(null);
219                 setMessage(null);
220                 String projName = projSelText.getText().trim();
221                 if (projName.length() == 0)
222                         return setErrorAndReturnFalse("No project specified");
223
224                 IWorkspace workspace = ResourcesPlugin.getWorkspace();
225                 IStatus status = workspace.validateName(projName, IResource.PROJECT);
226                 if (!status.isOK())
227                         return setErrorAndReturnFalse("Illegal project name: {0}: {1}", projName, status.getMessage());
228
229                 IProject project = workspace.getRoot().getProject(projName);
230                 if (!project.exists())
231                         return setErrorAndReturnFalse("Project {0} does not exist", projName);
232                 if (!project.isOpen())
233                         return setErrorAndReturnFalse("Project {0} is closed", projName);
234                 try
235                 {
236                         if (!project.hasNature(MograsimNature.NATURE_ID))
237                                 return setErrorAndReturnFalse("Project {0} is not a Mograsim project", projName);
238                 }
239                 catch (CoreException e)
240                 {
241                         return setErrorAndReturnFalse(e.getStatus().getMessage());
242                 }
243
244                 String mpmFileName = mpmFileSelText.getText().trim();
245                 if (mpmFileName.length() == 0)
246                         return setErrorAndReturnFalse("No MPM file specified");
247                 IResource mpmResource = project.findMember(mpmFileName);
248                 if (mpmResource == null || !mpmResource.exists())
249                         return setErrorAndReturnFalse("MPM file {0} does not exist", mpmFileName);
250                 if (mpmResource.getType() != IResource.FILE)
251                         return setErrorAndReturnFalse("MPM file {0} is not a file", mpmFileName);
252
253                 return true;
254         }
255
256         private boolean setErrorAndReturnFalse(String message, String... params)
257         {
258                 setErrorMessage(NLS.bind(message, params));
259                 return false;
260         }
261
262         @Override
263         public String getName()
264         {
265                 return "testlaunchconfigtabname";
266         }
267 }