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, this::chooseMograsimProject);
58 this.mpmFileSelText = createResourceSelectorGroup(innerParent, this::chooseMPMFile);
63 private Text createResourceSelectorGroup(Composite innerParent, Supplier<String> chooser)
65 Group projSelGroup = new Group(innerParent, SWT.NONE);
66 projSelGroup.setLayout(new GridLayout(2, false));
67 projSelGroup.setText("&Project:");
68 projSelGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
69 Text projSelText = new Text(projSelGroup, SWT.BORDER);
70 projSelText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
71 projSelText.addModifyListener(e -> updateLaunchConfigurationDialog());
72 Button projSelButton = new Button(projSelGroup, SWT.PUSH);
73 GridData projSelButtonData = new GridData();
74 projSelButtonData.widthHint = calculateWidthHint(projSelButton);
75 projSelButtonData.horizontalAlignment = SWT.FILL;
76 projSelButton.setLayoutData(projSelButtonData);
77 projSelButton.setText("&Browse...");
78 projSelButton.addListener(SWT.Selection, e ->
80 String chosen = chooser.get();
82 projSelText.setText(chosen);
87 private static int calculateWidthHint(Control c)
89 int wHint = new PixelConverter(c).convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
90 return Math.max(wHint, c.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
93 private String chooseMograsimProject()
95 WorkbenchLabelProvider renderer = new WorkbenchLabelProvider()
98 protected ImageDescriptor decorateImage(ImageDescriptor input, Object element)
100 return new ImageDescriptorWithMargins(input, new Point(22, 16));
103 ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), renderer);
104 dialog.setTitle("Project Selection");
105 dialog.setMessage("Select a Mograsim project");
106 dialog.setElements(filterOpenMograsimProjects(ResourcesPlugin.getWorkspace().getRoot().getProjects()));
107 if (dialog.open() == Window.OK)
108 return ((IProject) dialog.getFirstResult()).getName();
112 private String chooseMPMFile()
114 WorkbenchLabelProvider renderer = new WorkbenchLabelProvider()
117 protected ImageDescriptor decorateImage(ImageDescriptor input, Object element)
119 return new ImageDescriptorWithMargins(input, new Point(22, 16));
122 ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), renderer, new WorkbenchContentProvider());
123 dialog.setInput(getSelectedProject());
124 dialog.addFilter(new FileExtensionViewerFilter("mpm"));
126 if (dialog.open() == Window.OK)
127 return ((IResource) dialog.getResult()[0]).getProjectRelativePath().toPortableString();
131 private IProject getSelectedProject()
133 String projName = projSelText.getText().trim();
134 IWorkspace workspace = ResourcesPlugin.getWorkspace();
135 if (workspace.validateName(projName, IResource.PROJECT).isOK())
136 return workspace.getRoot().getProject(projName);
140 private static IProject[] filterOpenMograsimProjects(IProject[] projects)
142 return Arrays.stream(projects).filter(p ->
146 return p.isAccessible() && p.hasNature(MograsimNature.NATURE_ID);
148 catch (CoreException e)
150 throw new RuntimeException(e);
152 }).toArray(IProject[]::new);
156 public void setDefaults(ILaunchConfigurationWorkingCopy configuration)
158 // TODO don't let the user have to specify everything
162 public void initializeFrom(ILaunchConfiguration configuration)
164 String projName = "";
167 projName = configuration.getAttribute(MachineLaunchConfigType.PROJECT_ATTR, "");
169 catch (CoreException e)
171 setErrorMessage(e.getStatus().getMessage());
173 projSelText.setText(projName);
177 public void performApply(ILaunchConfigurationWorkingCopy configuration)
179 String projName = projSelText.getText().trim();
180 String mpmFileName = mpmFileSelText.getText().trim();
182 Set<IResource> associatedResources = new HashSet<>();
183 IWorkspace workspace = ResourcesPlugin.getWorkspace();
184 if (workspace.validateName(projName, IResource.PROJECT).isOK())
186 IProject project = workspace.getRoot().getProject(projName);
189 if (project != null && project.isAccessible() && project.hasNature(MograsimNature.NATURE_ID))
191 IResource mpmFile = project.findMember(mpmFileName);
192 if (mpmFile != null && mpmFile.exists() && mpmFile.getType() == IResource.FILE)
193 associatedResources.add(mpmFile);
195 associatedResources.add(project);
198 catch (CoreException e)
200 setErrorMessage(e.getStatus().getMessage());
203 configuration.setMappedResources(associatedResources.toArray(IResource[]::new));
204 configuration.setAttribute(MachineLaunchConfigType.PROJECT_ATTR, projName);
205 configuration.setAttribute(MachineLaunchConfigType.MPM_FILE_ATTR, mpmFileName);
209 public boolean isValid(ILaunchConfiguration launchConfig)
211 setErrorMessage(null);
213 String projName = projSelText.getText().trim();
214 if (projName.length() == 0)
215 return setErrorAndReturnFalse("No project specified");
217 IWorkspace workspace = ResourcesPlugin.getWorkspace();
218 IStatus status = workspace.validateName(projName, IResource.PROJECT);
220 return setErrorAndReturnFalse("Illegal project name: {0}: {1}", projName, status.getMessage());
222 IProject project = workspace.getRoot().getProject(projName);
223 if (!project.exists())
224 return setErrorAndReturnFalse("Project {0} does not exist", projName);
225 if (!project.isOpen())
226 return setErrorAndReturnFalse("Project {0} is closed", projName);
229 if (!project.hasNature(MograsimNature.NATURE_ID))
230 return setErrorAndReturnFalse("Project {0} is not a Mograsim project", projName);
232 catch (CoreException e)
234 return setErrorAndReturnFalse(e.getStatus().getMessage());
237 String mpmFileName = mpmFileSelText.getText().trim();
238 if (mpmFileName.length() == 0)
239 return setErrorAndReturnFalse("No MPM file specified");
240 IResource mpmResource = project.findMember(mpmFileName);
241 if (mpmResource == null || !mpmResource.exists())
242 return setErrorAndReturnFalse("MPM file {0} does not exist", mpmFileName);
243 if (mpmResource.getType() != IResource.FILE)
244 return setErrorAndReturnFalse("MPM file {0} is not a file", mpmFileName);
249 private boolean setErrorAndReturnFalse(String message, String... params)
251 setErrorMessage(NLS.bind(message, params));
256 public String getName()
258 return "testlaunchconfigtabname";