1 package net.mograsim.plugin.launch;
3 import java.util.Arrays;
4 import java.util.HashSet;
6 import java.util.function.Supplier;
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;
37 import net.mograsim.plugin.nature.MograsimNature;
38 import net.mograsim.plugin.util.FileExtensionViewerFilter;
39 import net.mograsim.plugin.util.ImageDescriptorWithMargins;
41 //a big part of this class is stolen from org.eclipse.jdt.debug.ui
42 public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab
44 private Text projSelText;
45 private Text mpmFileSelText;
48 public void createControl(Composite parent)
50 parent.setLayout(new FillLayout());
51 Composite innerParent = new Composite(parent, SWT.NONE);
52 setControl(innerParent);
54 innerParent.setLayout(new GridLayout());
56 this.projSelText = createResourceSelectorGroup(innerParent, "&Project:", this::chooseMograsimProject);
58 this.mpmFileSelText = createResourceSelectorGroup(innerParent, "&MPM:", this::chooseMPMFile);
63 private Text createResourceSelectorGroup(Composite innerParent, String groupName, Supplier<String> chooser)
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));
70 Text text = new Text(group, SWT.BORDER);
71 text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
72 text.addModifyListener(e -> updateLaunchConfigurationDialog());
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 ->
82 String chosen = chooser.get();
89 private static int calculateWidthHint(Control c)
91 int wHint = new PixelConverter(c).convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
92 return Math.max(wHint, c.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
95 private String chooseMograsimProject()
97 WorkbenchLabelProvider renderer = new WorkbenchLabelProvider()
100 protected ImageDescriptor decorateImage(ImageDescriptor input, Object element)
102 return new ImageDescriptorWithMargins(input, new Point(22, 16));
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();
114 private String chooseMPMFile()
116 WorkbenchLabelProvider renderer = new WorkbenchLabelProvider()
119 protected ImageDescriptor decorateImage(ImageDescriptor input, Object element)
121 return new ImageDescriptorWithMargins(input, new Point(22, 16));
124 ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), renderer, new WorkbenchContentProvider());
125 dialog.setInput(getSelectedProject());
126 dialog.addFilter(new FileExtensionViewerFilter("mpm"));
128 if (dialog.open() == Window.OK)
129 return ((IResource) dialog.getResult()[0]).getProjectRelativePath().toPortableString();
133 private IProject getSelectedProject()
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);
142 private static IProject[] filterOpenMograsimProjects(IProject[] projects)
144 return Arrays.stream(projects).filter(p ->
148 return p.isAccessible() && p.hasNature(MograsimNature.NATURE_ID);
150 catch (CoreException e)
152 throw new RuntimeException(e);
154 }).toArray(IProject[]::new);
158 public void setDefaults(ILaunchConfigurationWorkingCopy configuration)
160 // TODO don't let the user have to specify everything
164 public void initializeFrom(ILaunchConfiguration configuration)
166 projSelText.setText(getStringAttribSafe(configuration, MachineLaunchConfigType.PROJECT_ATTR, ""));
167 mpmFileSelText.setText(getStringAttribSafe(configuration, MachineLaunchConfigType.MPM_FILE_ATTR, ""));
170 private String getStringAttribSafe(ILaunchConfiguration configuration, String attrib, String defaultValue)
174 return configuration.getAttribute(attrib, defaultValue);
176 catch (CoreException e)
178 setErrorMessage(e.getStatus().getMessage());
184 public void performApply(ILaunchConfigurationWorkingCopy configuration)
186 String projName = projSelText.getText().trim();
187 String mpmFileName = mpmFileSelText.getText().trim();
189 Set<IResource> associatedResources = new HashSet<>();
190 IWorkspace workspace = ResourcesPlugin.getWorkspace();
191 if (workspace.validateName(projName, IResource.PROJECT).isOK())
193 IProject project = workspace.getRoot().getProject(projName);
196 if (project != null && project.isAccessible() && project.hasNature(MograsimNature.NATURE_ID))
198 IResource mpmFile = project.findMember(mpmFileName);
199 if (mpmFile != null && mpmFile.exists() && mpmFile.getType() == IResource.FILE)
200 associatedResources.add(mpmFile);
202 associatedResources.add(project);
205 catch (CoreException e)
207 setErrorMessage(e.getStatus().getMessage());
210 configuration.setMappedResources(associatedResources.toArray(IResource[]::new));
211 configuration.setAttribute(MachineLaunchConfigType.PROJECT_ATTR, projName);
212 configuration.setAttribute(MachineLaunchConfigType.MPM_FILE_ATTR, mpmFileName);
216 public boolean isValid(ILaunchConfiguration launchConfig)
218 setErrorMessage(null);
220 String projName = projSelText.getText().trim();
221 if (projName.length() == 0)
222 return setErrorAndReturnFalse("No project specified");
224 IWorkspace workspace = ResourcesPlugin.getWorkspace();
225 IStatus status = workspace.validateName(projName, IResource.PROJECT);
227 return setErrorAndReturnFalse("Illegal project name: {0}: {1}", projName, status.getMessage());
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);
236 if (!project.hasNature(MograsimNature.NATURE_ID))
237 return setErrorAndReturnFalse("Project {0} is not a Mograsim project", projName);
239 catch (CoreException e)
241 return setErrorAndReturnFalse(e.getStatus().getMessage());
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);
256 private boolean setErrorAndReturnFalse(String message, String... params)
258 setErrorMessage(NLS.bind(message, params));
263 public String getName()
265 return "testlaunchconfigtabname";