From: Christian Femers Date: Thu, 17 Oct 2019 02:23:36 +0000 (+0200) Subject: Added new Mograsim project wizard and updated getting started. X-Git-Url: https://mograsim.net/gitweb/?a=commitdiff_plain;h=804d41d604dfe055fc9ab2d311e0a30188db21e1;p=Mograsim.git Added new Mograsim project wizard and updated getting started. --- diff --git a/docs/getting_started.md b/docs/getting_started.md index f8ee36ac..9285f4fd 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -3,7 +3,7 @@ ## Prerequisites - [Java](http://jdk.java.net/) 11 or later (or [Oracle Implementation](https://www.oracle.com/technetwork/java/javase/downloads/index.html)) -- [Eclipse](https://www.eclipse.org/downloads/) 2019-03 or later (TODO: do earlier versions work?) +- [Eclipse](https://www.eclipse.org/downloads/) 2019-03 or later (Open question: do earlier versions work?) ## Install Mograsim @@ -21,19 +21,23 @@ Note: Currently, there is no online update site for Mograsim. You have to build ## Enable the Launch action set -1. Go to "Window" -> "Perspective" -> "Customize Perspective...". -2. Go to the tab "Action Set Availability". -3. Under "Available action sets", enable "Launch" (if it is not already enabled); click on "Apply and Close". +1. Go to "Window" -> "Perspective" -> "Open Perspective" + and select "Mograsim" or click "Other..." and then select Mograsim.
+ This can also be done by the perspective switcher on the right. ## Create a new Mograsim project -1. Create a new Eclipse project. (Go to "File" -> "New" -> "Project...", select "General" -> "Project".) -2. Add the Mograsim nature to the new project and set it up: - 1. Open the properties dialog of the new project. (Right-click on it, select Properties.) - 2. Go to the "Project Natures" page, click on "Add...". If a confirmation dialog pops up, confirm. - 3. Select "Mograsim Project Nature"; click on "OK". - 4. Click on "Apply and Close" and re-open the properties dialog. - 5. Go to the new "Mograsim" page, select "Am2900Simple", click on "Apply and Close". +1. Create a new Mograsim project. (Go to "File" -> "New" -> "Project...", select "Mograsim" -> "Mograsim + Project".) +2. Give it a project name and a Mograsim machine and finish. + +Alternatively, you can create a general Project and add the Mograsim nature to the new project and set it up: + +1. Open the properties dialog of the new project. (Right-click on it, select Properties.) +2. Go to the "Project Natures" page, click on "Add...". If a confirmation dialog pops up, confirm. +3. Select "Mograsim Project Nature"; click on "OK". +4. Click on "Apply and Close" and re-open the properties dialog. +5. Go to the new "Mograsim" page, select "Am2900Simple", click on "Apply and Close". ## Write a MPM file (containing the microprogram) @@ -86,7 +90,7 @@ The MPM can be modified by this line. This is not recommended, however, because ### Memory view -1. In the Memory view, click on the green +, enter 0 and click on "OK". +1. Select the preferred numerical representation 2. Right-click on the table -> "Format...". 3. Select 16 units per row and one unit per column. (8 units per row if 16 don't fit on the screen.) @@ -94,7 +98,7 @@ The table now displays the contents of the currently running machine. At this mo ### Register view -1. Expand the pseudo register group. +1. Expand the register group you would like to view. It should contain the registers R0-R15 as well as the Q register. All of them should be 0, displayed as a bitstring diff --git a/plugins/net.mograsim.plugin.core/plugin.xml b/plugins/net.mograsim.plugin.core/plugin.xml index 5289133d..959e6a84 100644 --- a/plugins/net.mograsim.plugin.core/plugin.xml +++ b/plugins/net.mograsim.plugin.core/plugin.xml @@ -418,6 +418,22 @@ %wizards.newWizards.mem.desc + + + %wizards.newWizards.project.desc + + + + @@ -542,6 +558,9 @@ + + diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/wizards/newWizards/MograsimSettingsPage.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/wizards/newWizards/MograsimSettingsPage.java new file mode 100644 index 00000000..390cefba --- /dev/null +++ b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/wizards/newWizards/MograsimSettingsPage.java @@ -0,0 +1,132 @@ +package net.mograsim.plugin.wizards.newWizards; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + +import net.mograsim.plugin.nature.MachineContextSwtTools; +import net.mograsim.plugin.nature.MachineContextSwtTools.MachineCombo; + +public class MograsimSettingsPage extends WizardPage +{ + private MachineCombo machineSelect; + + public MograsimSettingsPage(IStructuredSelection selection) + { + this(); + } + + public MograsimSettingsPage() + { + super("Mograsim Project Settings"); + setPageComplete(false); + } + + @Override + public void createControl(Composite parent) + { + Composite composite = new Composite(parent, SWT.NULL); + initializeDialogUnits(parent); + + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + addFirstSection(composite); + addSeparator(composite); + addSecondSection(composite); + + // Show description on opening + setErrorMessage(null); + setMessage(null); + setControl(composite); + Dialog.applyDialogFont(composite); + } + + private void addFirstSection(Composite parent) + { + Composite composite = createDefaultComposite(parent); + + // Label for path field + Label pathLabel = new Label(composite, SWT.NONE); + pathLabel.setText("Please configure the machine that Mograsim should use:"); + } + + private void addSeparator(Composite parent) + { + Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); + GridData gridData = new GridData(); + gridData.horizontalAlignment = GridData.FILL; + gridData.grabExcessHorizontalSpace = true; + separator.setLayoutData(gridData); + } + + private Composite createDefaultComposite(Composite parent) + { + Composite composite = new Composite(parent, SWT.NULL); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + composite.setLayout(layout); + + GridData data = new GridData(); + data.verticalAlignment = GridData.FILL; + data.horizontalAlignment = GridData.FILL; + composite.setLayoutData(data); + + return composite; + } + + private void addSecondSection(Composite parent) + { + Composite composite = createDefaultComposite(parent); + + // Label for machine + Label ownerLabel = new Label(composite, SWT.NONE); + ownerLabel.setText("Machine definition"); + + // Machine choice + machineSelect = MachineContextSwtTools.createMachineSelector(composite, SWT.NONE); + machineSelect.addListener(md -> setPageComplete(isValid())); + GridData gd = new GridData(); +// machineSelect.setLayoutData(gd); + } + + public boolean isValid() + { + return machineSelect.isValidSelection(); + } + + @Override + public void setVisible(boolean visible) + { + super.setVisible(visible); + if (visible) + { +// machineSelect.getCombo().getCCombo().setFocus(); + } + } + + public final MograsimProjectConfig getMograsimProjectConfig() + { + return new MograsimProjectConfig(machineSelect.getSelection().getId()); + } + + public static final class MograsimProjectConfig + { + final String machineId; + + public MograsimProjectConfig(String machineId) + { + this.machineId = machineId; + } + + public final String getMachineId() + { + return machineId; + } + } +} diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/wizards/newWizards/NewMograsimProject.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/wizards/newWizards/NewMograsimProject.java new file mode 100644 index 00000000..6178a9de --- /dev/null +++ b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/wizards/newWizards/NewMograsimProject.java @@ -0,0 +1,552 @@ +package net.mograsim.plugin.wizards.newWizards; + +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Set; +import java.util.StringTokenizer; + +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IResourceStatus; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExecutableExtension; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.MessageDialogWithToggle; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IPerspectiveDescriptor; +import org.eclipse.ui.IPerspectiveRegistry; +import org.eclipse.ui.IPluginContribution; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPreferenceConstants; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkingSet; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.WorkbenchException; +import org.eclipse.ui.activities.IActivityManager; +import org.eclipse.ui.activities.IIdentifier; +import org.eclipse.ui.activities.IWorkbenchActivitySupport; +import org.eclipse.ui.activities.WorkbenchActivityHelper; +import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.ide.undo.CreateProjectOperation; +import org.eclipse.ui.ide.undo.WorkspaceUndoUtil; +import org.eclipse.ui.internal.IPreferenceConstants; +import org.eclipse.ui.internal.WorkbenchPlugin; +import org.eclipse.ui.internal.ide.IDEInternalPreferences; +import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; +import org.eclipse.ui.internal.ide.StatusUtil; +import org.eclipse.ui.internal.registry.PerspectiveDescriptor; +import org.eclipse.ui.internal.util.PrefUtil; +import org.eclipse.ui.internal.wizards.newresource.ResourceMessages; +import org.eclipse.ui.statushandlers.StatusAdapter; +import org.eclipse.ui.statushandlers.StatusManager; +import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard; +import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard; + +import net.mograsim.plugin.nature.AddMograsimNatureHandler; + +/** + * This is a copy of {@link BasicNewProjectResourceWizard} for Mograsim. (This is done to remove the reference tab) + * + * + * @author Christian Femers + * + */ +public class NewMograsimProject extends BasicNewResourceWizard implements IExecutableExtension +{ + + private WizardNewProjectCreationPage mainPage; + private MograsimSettingsPage mograsimPage; + +// cache of newly-created project + private IProject newProject; + + /** + * The config element which declares this wizard. + */ + private IConfigurationElement configElement; + + private static String WINDOW_PROBLEMS_TITLE = ResourceMessages.NewProject_errorOpeningWindow; + + /** + * Extension attribute name for final perspective. + */ + private static final String FINAL_PERSPECTIVE = "finalPerspective"; //$NON-NLS-1$ + + /** + * Extension attribute name for preferred perspectives. + */ + private static final String PREFERRED_PERSPECTIVES = "preferredPerspectives"; //$NON-NLS-1$ + + /** + * Creates a wizard for creating a new project resource in the workspace. + */ + public NewMograsimProject() + { + IDialogSettings workbenchSettings = IDEWorkbenchPlugin.getDefault().getDialogSettings(); + IDialogSettings section = workbenchSettings.getSection("BasicNewProjectResourceWizard");//$NON-NLS-1$ + if (section == null) + { + section = workbenchSettings.addNewSection("BasicNewProjectResourceWizard");//$NON-NLS-1$ + } + setDialogSettings(section); + + } + + @Override + public void addPages() + { + super.addPages(); + + mainPage = new WizardNewProjectCreationPage("basicNewProjectPage") //$NON-NLS-1$ + { + @Override + public void createControl(Composite parent) + { + super.createControl(parent); + createWorkingSetGroup((Composite) getControl(), getSelection(), new String[] { "org.eclipse.ui.resourceWorkingSetPage" }); //$NON-NLS-1$ + Dialog.applyDialogFont(getControl()); + } + }; + mainPage.setTitle("New Mograsim Project"); + mainPage.setDescription(ResourceMessages.NewProject_description); + this.addPage(mainPage); + + mograsimPage = new MograsimSettingsPage() + { + @Override + public void createControl(Composite parent) + { + super.createControl(parent); + Dialog.applyDialogFont(getControl()); + } + }; + mograsimPage.setDescription("Configure the Mograsim Project and its Machine"); + this.addPage(mograsimPage); + } + + /** + * Creates a new project resource with the selected name. + *

+ * In normal usage, this method is invoked after the user has pressed Finish on the wizard; the enablement of the Finish button implies + * that all controls on the pages currently contain valid values. + *

+ *

+ * Note that this wizard caches the new project once it has been successfully created; subsequent invocations of this method will answer + * the same project resource without attempting to create it again. + *

+ * + * @return the created project resource, or null if the project was not created + */ + private IProject createNewProject() + { + if (newProject != null) + { + return newProject; + } + +// get a project handle + final IProject newProjectHandle = mainPage.getProjectHandle(); + +// get a project descriptor + URI location = null; + if (!mainPage.useDefaults()) + { + location = mainPage.getLocationURI(); + } + + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + final IProjectDescription description = workspace.newProjectDescription(newProjectHandle.getName()); + description.setLocationURI(location); + +// create the new project operation + IRunnableWithProgress op = monitor -> + { + CreateProjectOperation op1 = new CreateProjectOperation(description, ResourceMessages.NewProject_windowTitle); + try + { +// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=219901 +// directly execute the operation so that the undo state is +// not preserved. Making this undoable resulted in too many +// accidental file deletions. + op1.execute(monitor, WorkspaceUndoUtil.getUIInfoAdapter(getShell())); + } + catch (ExecutionException e) + { + throw new InvocationTargetException(e); + } + }; + +// run the new project creation operation + try + { + getContainer().run(true, true, op); + } + catch (InterruptedException e) + { + return null; + } + catch (InvocationTargetException e) + { + Throwable t = e.getTargetException(); + if (t instanceof ExecutionException && t.getCause() instanceof CoreException) + { + CoreException cause = (CoreException) t.getCause(); + StatusAdapter status; + if (cause.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) + { + status = new StatusAdapter(StatusUtil.newStatus(IStatus.WARNING, + NLS.bind(ResourceMessages.NewProject_caseVariantExistsError, newProjectHandle.getName()), cause)); + } else + { + status = new StatusAdapter( + StatusUtil.newStatus(cause.getStatus().getSeverity(), ResourceMessages.NewProject_errorMessage, cause)); + } + status.setProperty(StatusAdapter.TITLE_PROPERTY, ResourceMessages.NewProject_errorMessage); + StatusManager.getManager().handle(status, StatusManager.BLOCK); + } else + { + StatusAdapter status = new StatusAdapter(new Status(IStatus.WARNING, IDEWorkbenchPlugin.IDE_WORKBENCH, 0, + NLS.bind(ResourceMessages.NewProject_internalError, t.getMessage()), t)); + status.setProperty(StatusAdapter.TITLE_PROPERTY, ResourceMessages.NewProject_errorMessage); + StatusManager.getManager().handle(status, StatusManager.LOG | StatusManager.BLOCK); + } + return null; + } + + newProject = newProjectHandle; + + return newProject; + } + + /** + * Returns the newly created project. + * + * @return the created project, or null if project not created + */ + public IProject getNewProject() + { + return newProject; + } + + @Override + public void init(IWorkbench workbench, IStructuredSelection currentSelection) + { + super.init(workbench, currentSelection); + setNeedsProgressMonitor(true); + setWindowTitle("New Mograsim Project"); + } + + @Override + protected void initializeDefaultPageImageDescriptor() + { + ImageDescriptor desc = IDEWorkbenchPlugin.getIDEImageDescriptor("wizban/newprj_wiz.png");//$NON-NLS-1$ + setDefaultPageImageDescriptor(desc); + } + + private static void openInNewWindow(IPerspectiveDescriptor desc) + { + +// Open the page. + try + { + PlatformUI.getWorkbench().openWorkbenchWindow(desc.getId(), ResourcesPlugin.getWorkspace().getRoot()); + } + catch (WorkbenchException e) + { + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window != null) + { + ErrorDialog.openError(window.getShell(), WINDOW_PROBLEMS_TITLE, e.getMessage(), e.getStatus()); + } + } + } + + @Override + public boolean performFinish() + { + createNewProject(); + + if (newProject == null) + { + return false; + } + + IWorkingSet[] workingSets = mainPage.getSelectedWorkingSets(); + getWorkbench().getWorkingSetManager().addToWorkingSets(newProject, workingSets); + + try + { + AddMograsimNatureHandler.addNatureAndConfigure(getNewProject(), mograsimPage.getMograsimProjectConfig().getMachineId()); + } + catch (CoreException e) + { + e.printStackTrace(); + } + + updatePerspective(); + selectAndReveal(newProject); + + return true; + } + + private static void replaceCurrentPerspective(IPerspectiveDescriptor persp) + { + +// Get the active page. + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) + { + return; + } + IWorkbenchPage page = window.getActivePage(); + if (page == null) + { + return; + } + +// Set the perspective. + page.setPerspective(persp); + } + + /** + * Stores the configuration element for the wizard. The config element will be used in performFinish to set the result + * perspective. + */ + @Override + public void setInitializationData(IConfigurationElement cfig, String propertyName, Object data) + { + configElement = cfig; + } + + /** + * Updates the perspective for the active page within the window. + */ + protected void updatePerspective() + { + updatePerspective(configElement); + } + + /** + * Updates the perspective based on the current settings in the Workbench/Perspectives preference page. + * + * Use the setting for the new perspective opening if we are set to open in a new perspective. + *

+ * A new project wizard class will need to implement the IExecutableExtension interface so as to gain access to the + * wizard's IConfigurationElement. That is the configuration element to pass into this method. + *

+ * + * @param configElement - the element we are updating with + * + * @see IPreferenceConstants#OPM_NEW_WINDOW + * @see IPreferenceConstants#OPM_ACTIVE_PAGE + * @see IWorkbenchPreferenceConstants#NO_NEW_PERSPECTIVE + */ + public static void updatePerspective(IConfigurationElement configElement) + { +// Do not change perspective if the configuration element is +// not specified. + if (configElement == null) + { + return; + } + +// Retrieve the new project open perspective preference setting + String perspSetting = PrefUtil.getAPIPreferenceStore().getString(IDE.Preferences.PROJECT_OPEN_NEW_PERSPECTIVE); + + String promptSetting = IDEWorkbenchPlugin.getDefault().getPreferenceStore() + .getString(IDEInternalPreferences.PROJECT_SWITCH_PERSP_MODE); + +// Return if do not switch perspective setting and are not prompting + if (!(promptSetting.equals(MessageDialogWithToggle.PROMPT)) + && perspSetting.equals(IWorkbenchPreferenceConstants.NO_NEW_PERSPECTIVE)) + { + return; + } + +// Read the requested perspective id to be opened. + String finalPerspId = configElement.getAttribute(FINAL_PERSPECTIVE); + if (finalPerspId == null) + { + return; + } + +// Map perspective id to descriptor. + IPerspectiveRegistry reg = PlatformUI.getWorkbench().getPerspectiveRegistry(); + +// leave this code in - the perspective of a given project may map to +// activities other than those that the wizard itself maps to. + IPerspectiveDescriptor finalPersp = reg.findPerspectiveWithId(finalPerspId); + if (finalPersp != null && finalPersp instanceof IPluginContribution) + { + IPluginContribution contribution = (IPluginContribution) finalPersp; + if (contribution.getPluginId() != null) + { + IWorkbenchActivitySupport workbenchActivitySupport = PlatformUI.getWorkbench().getActivitySupport(); + IActivityManager activityManager = workbenchActivitySupport.getActivityManager(); + IIdentifier identifier = activityManager.getIdentifier(WorkbenchActivityHelper.createUnifiedId(contribution)); + Set idActivities = identifier.getActivityIds(); + + if (!idActivities.isEmpty()) + { + Set enabledIds = new HashSet<>(activityManager.getEnabledActivityIds()); + + if (enabledIds.addAll(idActivities)) + { + workbenchActivitySupport.setEnabledActivityIds(enabledIds); + } + } + } + } else + { + IDEWorkbenchPlugin.log("Unable to find persective " //$NON-NLS-1$ + + finalPerspId + " in BasicNewProjectResourceWizard.updatePerspective"); //$NON-NLS-1$ + return; + } + +// gather the preferred perspectives +// always consider the final perspective (and those derived from it) +// to be preferred + ArrayList preferredPerspIds = new ArrayList<>(); + addPerspectiveAndDescendants(preferredPerspIds, finalPerspId); + String preferred = configElement.getAttribute(PREFERRED_PERSPECTIVES); + if (preferred != null) + { + StringTokenizer tok = new StringTokenizer(preferred, " \t\n\r\f,"); //$NON-NLS-1$ + while (tok.hasMoreTokens()) + { + addPerspectiveAndDescendants(preferredPerspIds, tok.nextToken()); + } + } + + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window != null) + { + IWorkbenchPage page = window.getActivePage(); + if (page != null) + { + IPerspectiveDescriptor currentPersp = page.getPerspective(); + + // don't switch if the current perspective is a preferred + // perspective + if (currentPersp != null && preferredPerspIds.contains(currentPersp.getId())) + { + return; + } + } + + // prompt the user to switch + if (!confirmPerspectiveSwitch(window, finalPersp)) + { + return; + } + } + + int workbenchPerspectiveSetting = WorkbenchPlugin.getDefault().getPreferenceStore().getInt(IPreferenceConstants.OPEN_PERSP_MODE); + +// open perspective in new window setting + if (workbenchPerspectiveSetting == IPreferenceConstants.OPM_NEW_WINDOW) + { + openInNewWindow(finalPersp); + return; + } + +// replace active perspective setting otherwise + replaceCurrentPerspective(finalPersp); + } + + /** + * Adds to the list all perspective IDs in the Workbench who's original ID matches the given ID. + * + * @param perspectiveIds the list of perspective IDs to supplement. + * @param id the id to query. + * @since 3.0 + */ + private static void addPerspectiveAndDescendants(List perspectiveIds, String id) + { + IPerspectiveRegistry registry = PlatformUI.getWorkbench().getPerspectiveRegistry(); + for (IPerspectiveDescriptor perspective : registry.getPerspectives()) + { + // @issue illegal ref to workbench internal class; + // consider adding getOriginalId() as API on IPerspectiveDescriptor + PerspectiveDescriptor descriptor = ((PerspectiveDescriptor) perspective); + if (descriptor.getOriginalId().equals(id)) + { + perspectiveIds.add(descriptor.getId()); + } + } + } + + /** + * Prompts the user for whether to switch perspectives. + * + * @param window The workbench window in which to switch perspectives; must not be null + * @param finalPersp The perspective to switch to; must not be null. + * + * @return true if it's OK to switch, false otherwise + */ + private static boolean confirmPerspectiveSwitch(IWorkbenchWindow window, IPerspectiveDescriptor finalPersp) + { + IPreferenceStore store = IDEWorkbenchPlugin.getDefault().getPreferenceStore(); + String pspm = store.getString(IDEInternalPreferences.PROJECT_SWITCH_PERSP_MODE); + if (!IDEInternalPreferences.PSPM_PROMPT.equals(pspm)) + { + // Return whether or not we should always switch + return IDEInternalPreferences.PSPM_ALWAYS.equals(pspm); + } + String desc = finalPersp.getDescription(); + String message; + if (desc == null || desc.length() == 0) + message = NLS.bind(ResourceMessages.NewProject_perspSwitchMessage, finalPersp.getLabel()); + else + message = NLS.bind(ResourceMessages.NewProject_perspSwitchMessageWithDesc, new String[] { finalPersp.getLabel(), desc }); + + LinkedHashMap buttonLabelToId = new LinkedHashMap<>(); + buttonLabelToId.put(ResourceMessages.NewProject_perspSwitchButtonLabel, IDialogConstants.YES_ID); + buttonLabelToId.put(IDialogConstants.NO_LABEL, IDialogConstants.NO_ID); + MessageDialogWithToggle dialog = MessageDialogWithToggle.open(MessageDialog.QUESTION, window.getShell(), + ResourceMessages.NewProject_perspSwitchTitle, message, null, false, store, IDEInternalPreferences.PROJECT_SWITCH_PERSP_MODE, + SWT.NONE, buttonLabelToId); + int result = dialog.getReturnCode(); + +// If we are not going to prompt anymore propogate the choice. + if (dialog.getToggleState()) + { + String preferenceValue; + if (result == IDialogConstants.YES_ID) + { + // Doesn't matter if it is replace or new window + // as we are going to use the open perspective setting + preferenceValue = IWorkbenchPreferenceConstants.OPEN_PERSPECTIVE_REPLACE; + } else + { + preferenceValue = IWorkbenchPreferenceConstants.NO_NEW_PERSPECTIVE; + } + + // update PROJECT_OPEN_NEW_PERSPECTIVE to correspond + PrefUtil.getAPIPreferenceStore().setValue(IDE.Preferences.PROJECT_OPEN_NEW_PERSPECTIVE, preferenceValue); + } + return result == IDialogConstants.YES_ID; + } +} \ No newline at end of file