Finished MPROM support. Fixes #10
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / launch / MainMachineLaunchConfigTab.java
index 6579efc..fbbe264 100644 (file)
@@ -3,6 +3,7 @@ package net.mograsim.plugin.launch;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.function.Supplier;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
@@ -26,18 +27,25 @@ import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
+import org.eclipse.ui.model.WorkbenchContentProvider;
 import org.eclipse.ui.model.WorkbenchLabelProvider;
 
 import net.mograsim.plugin.nature.MograsimNature;
+import net.mograsim.plugin.util.FileExtensionViewerFilter;
 import net.mograsim.plugin.util.ImageDescriptorWithMargins;
+import net.mograsim.plugin.util.ProjectViewerFilter;
 
 //a big part of this class is stolen from org.eclipse.jdt.debug.ui
 public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab
 {
        private Text projSelText;
+       private Text mpmFileSelText;
+       private Text mpromFileSelText;
+       private Text initialRAMFileSelText;
 
        @Override
        public void createControl(Composite parent)
@@ -46,29 +54,42 @@ public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab
                Composite innerParent = new Composite(parent, SWT.NONE);
                setControl(innerParent);
 
-               innerParent.setLayout(new GridLayout());
+               innerParent.setLayout(new GridLayout(3, false));
 
-               Group projSelGroup = new Group(innerParent, SWT.NONE);
-               projSelGroup.setLayout(new GridLayout(2, false));
-               projSelGroup.setText("&Project:");
-               projSelGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-               projSelText = new Text(projSelGroup, SWT.BORDER);
-               projSelText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
-               projSelText.addModifyListener(e -> updateLaunchConfigurationDialog());
-               Button projSelButton = new Button(projSelGroup, SWT.PUSH);
+               this.projSelText = addResourceSelector(innerParent, "P&roject:", this::chooseMograsimProject);
+
+               this.mpmFileSelText = addResourceSelector(innerParent, "&MPM:", this::chooseMPMFile);
+
+               this.mpromFileSelText = addResourceSelector(innerParent, "M&PROM:", this::chooseMPROMFile);
+
+               this.initialRAMFileSelText = addResourceSelector(innerParent, "Initial &RAM (optional):", this::chooseInitialRAMFile);
+       }
+
+       private Text addResourceSelector(Composite innerParent, String label, Supplier<String> chooser)
+       {
+               Label swtLabel = new Label(innerParent, SWT.NONE);
+               swtLabel.setText(label);
+               swtLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
+
+               Text text = new Text(innerParent, SWT.BORDER);
+               text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+               text.addModifyListener(e -> updateLaunchConfigurationDialog());
+
+               swtLabel.addListener(SWT.FocusIn, e -> text.setFocus());
+
+               Button browseButton = new Button(innerParent, SWT.PUSH);
                GridData projSelButtonData = new GridData();
-               projSelButtonData.widthHint = calculateWidthHint(projSelButton);
+               projSelButtonData.widthHint = calculateWidthHint(browseButton);
                projSelButtonData.horizontalAlignment = SWT.FILL;
-               projSelButton.setLayoutData(projSelButtonData);
-               projSelButton.setText("&Browse...");
-               projSelButton.addListener(SWT.Selection, e ->
+               browseButton.setLayoutData(projSelButtonData);
+               browseButton.setText("&Browse...");
+               browseButton.addListener(SWT.Selection, e ->
                {
-                       IProject choosedProject = chooseMograsimProject();
-                       if (choosedProject != null)
-                               projSelText.setText(choosedProject.getName());
+                       String chosen = chooser.get();
+                       if (chosen != null)
+                               text.setText(chosen);
                });
-
-               // TODO MPM / RAM selectors
+               return text;
        }
 
        private static int calculateWidthHint(Control c)
@@ -77,22 +98,62 @@ public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab
                return Math.max(wHint, c.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
        }
 
-       private IProject chooseMograsimProject()
+       private String chooseMograsimProject()
        {
+               // TODO this seems very ugly, especially hardcoded width/height
                WorkbenchLabelProvider renderer = new WorkbenchLabelProvider()
                {
                        @Override
                        protected ImageDescriptor decorateImage(ImageDescriptor input, Object element)
                        {
-                               return new ImageDescriptorWithMargins(input, new Point(22, 16));
+                               return new ImageDescriptorWithMargins(input, new Point(20, 16));
                        }
                };
                ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), renderer);
-               dialog.setTitle("title");
-               dialog.setMessage("message");
+               dialog.setTitle("Project Selection");
+               dialog.setMessage("Select a Mograsim project");
                dialog.setElements(filterOpenMograsimProjects(ResourcesPlugin.getWorkspace().getRoot().getProjects()));
                if (dialog.open() == Window.OK)
-                       return (IProject) dialog.getFirstResult();
+                       return ((IProject) dialog.getFirstResult()).getName();
+               return null;
+       }
+
+       private String chooseMPMFile()
+       {
+               return chooseFile("MPM", "mpm");
+       }
+
+       private String chooseMPROMFile()
+       {
+               return chooseFile("MPROM", "mprom");
+       }
+
+       private String chooseInitialRAMFile()
+       {
+               return chooseFile("Initial RAM", "mem");
+       }
+
+       private String chooseFile(String type, String fileext)
+       {
+               ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), new WorkbenchLabelProvider(),
+                               new WorkbenchContentProvider());
+               dialog.setTitle(type + " Selection");
+               dialog.setMessage("Select a ." + fileext + " file");
+               dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
+               dialog.addFilter(new FileExtensionViewerFilter(fileext));
+               dialog.addFilter(new ProjectViewerFilter(getSelectedProject()));
+
+               if (dialog.open() == Window.OK)
+                       return ((IResource) dialog.getResult()[0]).getProjectRelativePath().toPortableString();
+               return null;
+       }
+
+       private IProject getSelectedProject()
+       {
+               String projName = projSelText.getText().trim();
+               IWorkspace workspace = ResourcesPlugin.getWorkspace();
+               if (workspace.validateName(projName, IResource.PROJECT).isOK())
+                       return workspace.getRoot().getProject(projName);
                return null;
        }
 
@@ -120,31 +181,56 @@ public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab
        @Override
        public void initializeFrom(ILaunchConfiguration configuration)
        {
-               String projName = "";
+               projSelText.setText(getStringAttribSafe(configuration, MachineLaunchConfigType.PROJECT_ATTR, ""));
+               mpmFileSelText.setText(getStringAttribSafe(configuration, MachineLaunchConfigType.MPM_FILE_ATTR, ""));
+               mpromFileSelText.setText(getStringAttribSafe(configuration, MachineLaunchConfigType.MPROM_FILE_ATTR, ""));
+               initialRAMFileSelText.setText(getStringAttribSafe(configuration, MachineLaunchConfigType.INITIAL_RAM_FILE_ATTR, ""));
+       }
+
+       private String getStringAttribSafe(ILaunchConfiguration configuration, String attrib, String defaultValue)
+       {
                try
                {
-                       projName = configuration.getAttribute(MachineLaunchConfigType.PROJECT_ATTR, "");
+                       return configuration.getAttribute(attrib, defaultValue);
                }
                catch (CoreException e)
                {
                        setErrorMessage(e.getStatus().getMessage());
                }
-               projSelText.setText(projName);
+               return defaultValue;
        }
 
        @Override
        public void performApply(ILaunchConfigurationWorkingCopy configuration)
        {
-               Set<IResource> associatedResources = new HashSet<>();
                String projName = projSelText.getText().trim();
-               if (projName.length() != 0)
+               String mpmFileName = mpmFileSelText.getText().trim();
+               String mpromFileName = mpromFileSelText.getText().trim();
+               String initialRAMFileName = initialRAMFileSelText.getText().trim();
+
+               Set<IResource> associatedResources = new HashSet<>();
+               IWorkspace workspace = ResourcesPlugin.getWorkspace();
+               if (workspace.validateName(projName, IResource.PROJECT).isOK())
                {
-                       IWorkspace workspace = ResourcesPlugin.getWorkspace();
                        IProject project = workspace.getRoot().getProject(projName);
                        try
                        {
                                if (project != null && project.isAccessible() && project.hasNature(MograsimNature.NATURE_ID))
+                               {
                                        associatedResources.add(project);
+
+                                       IResource mpmFile = project.findMember(mpmFileName);
+                                       if (mpmFile != null && mpmFile.exists() && mpmFile.getType() == IResource.FILE)
+                                               associatedResources.add(mpmFile);
+
+                                       IResource mpromFile = project.findMember(mpromFileName);
+                                       if (mpromFile != null && mpromFile.exists() && mpromFile.getType() == IResource.FILE)
+                                               associatedResources.add(mpromFile);
+
+                                       IResource ramFile = project.findMember(initialRAMFileName);
+                                       if (ramFile != null && ramFile.exists() && ramFile.getType() == IResource.FILE)
+                                               associatedResources.add(ramFile);
+                               }
                        }
                        catch (CoreException e)
                        {
@@ -153,6 +239,9 @@ public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab
                }
                configuration.setMappedResources(associatedResources.toArray(IResource[]::new));
                configuration.setAttribute(MachineLaunchConfigType.PROJECT_ATTR, projName);
+               configuration.setAttribute(MachineLaunchConfigType.MPM_FILE_ATTR, mpmFileName);
+               configuration.setAttribute(MachineLaunchConfigType.MPROM_FILE_ATTR, mpromFileName);
+               configuration.setAttribute(MachineLaunchConfigType.INITIAL_RAM_FILE_ATTR, initialRAMFileName);
        }
 
        @Override
@@ -162,47 +251,69 @@ public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab
                setMessage(null);
                String projName = projSelText.getText().trim();
                if (projName.length() == 0)
-               {
-                       setErrorMessage("No project specified");
-                       return false;
-               }
+                       return setErrorAndReturnFalse("No project specified");
+
                IWorkspace workspace = ResourcesPlugin.getWorkspace();
                IStatus status = workspace.validateName(projName, IResource.PROJECT);
                if (!status.isOK())
-               {
-                       setErrorMessage(NLS.bind("Illegal project name: {0}", new String[] { status.getMessage() }));
-                       return false;
-               }
+                       return setErrorAndReturnFalse("Illegal project name: {0}: {1}", projName, status.getMessage());
+
                IProject project = workspace.getRoot().getProject(projName);
                if (!project.exists())
-               {
-                       setErrorMessage(NLS.bind("Project {0} does not exist", new String[] { projName }));
-                       return false;
-               }
+                       return setErrorAndReturnFalse("Project {0} does not exist", projName);
                if (!project.isOpen())
-               {
-                       setErrorMessage(NLS.bind("Project {0} is closed", new String[] { projName }));
-                       return false;
-               }
+                       return setErrorAndReturnFalse("Project {0} is closed", projName);
                try
                {
                        if (!project.hasNature(MograsimNature.NATURE_ID))
-                       {
-                               setErrorMessage(NLS.bind("Project {0} is not a Mograsim project", new String[] { projName }));
-                               return false;
-                       }
+                               return setErrorAndReturnFalse("Project {0} is not a Mograsim project", projName);
                }
                catch (CoreException e)
                {
-                       setErrorMessage(e.getStatus().getMessage());
-                       return false;
+                       return setErrorAndReturnFalse(e.getStatus().getMessage());
+               }
+
+               String mpmFileName = mpmFileSelText.getText().trim();
+               if (mpmFileName.length() == 0)
+                       return setErrorAndReturnFalse("No MPM file specified");
+               IResource mpmResource = project.findMember(mpmFileName);
+               if (mpmResource == null || !mpmResource.exists())
+                       return setErrorAndReturnFalse("MPM file {0} does not exist", mpmFileName);
+               if (mpmResource.getType() != IResource.FILE)
+                       return setErrorAndReturnFalse("MPM file {0} is not a file", mpmFileName);
+
+               String mpromFileName = mpromFileSelText.getText().trim();
+               if (mpromFileName.length() > 0)
+               {
+                       IResource mpromResource = project.findMember(mpromFileName);
+                       if (mpromResource == null || !mpromResource.exists())
+                               return setErrorAndReturnFalse("MPROM file {0} does not exist", mpromFileName);
+                       if (mpromResource.getType() != IResource.FILE)
+                               return setErrorAndReturnFalse("MPROM file {0} is not a file", mpromFileName);
+               }
+
+               String initialRAMFileName = initialRAMFileSelText.getText().trim();
+               if (initialRAMFileName.length() > 0)
+               {
+                       IResource initialRAMResource = project.findMember(initialRAMFileName);
+                       if (initialRAMResource == null || !initialRAMResource.exists())
+                               return setErrorAndReturnFalse("Initial RAM file {0} does not exist", initialRAMFileName);
+                       if (initialRAMResource.getType() != IResource.FILE)
+                               return setErrorAndReturnFalse("Initial RAM file {0} is not a file", initialRAMFileName);
                }
+
                return true;
        }
 
+       private boolean setErrorAndReturnFalse(String message, String... params)
+       {
+               setErrorMessage(NLS.bind(message, params));
+               return false;
+       }
+
        @Override
        public String getName()
        {
-               return "testlaunchconfigtabname";
+               return "Main";
        }
 }
\ No newline at end of file