1 package net.mograsim.plugin.wizards.newWizards;
3 import java.lang.reflect.InvocationTargetException;
5 import java.util.ArrayList;
6 import java.util.HashSet;
7 import java.util.LinkedHashMap;
10 import java.util.StringTokenizer;
12 import org.eclipse.core.commands.ExecutionException;
13 import org.eclipse.core.resources.IProject;
14 import org.eclipse.core.resources.IProjectDescription;
15 import org.eclipse.core.resources.IResourceStatus;
16 import org.eclipse.core.resources.IWorkspace;
17 import org.eclipse.core.resources.ResourcesPlugin;
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.core.runtime.IConfigurationElement;
20 import org.eclipse.core.runtime.IExecutableExtension;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.Status;
23 import org.eclipse.jface.dialogs.Dialog;
24 import org.eclipse.jface.dialogs.ErrorDialog;
25 import org.eclipse.jface.dialogs.IDialogConstants;
26 import org.eclipse.jface.dialogs.IDialogSettings;
27 import org.eclipse.jface.dialogs.MessageDialog;
28 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
29 import org.eclipse.jface.operation.IRunnableWithProgress;
30 import org.eclipse.jface.preference.IPreferenceStore;
31 import org.eclipse.jface.resource.ImageDescriptor;
32 import org.eclipse.jface.viewers.IStructuredSelection;
33 import org.eclipse.osgi.util.NLS;
34 import org.eclipse.swt.SWT;
35 import org.eclipse.swt.widgets.Composite;
36 import org.eclipse.ui.IPerspectiveDescriptor;
37 import org.eclipse.ui.IPerspectiveRegistry;
38 import org.eclipse.ui.IPluginContribution;
39 import org.eclipse.ui.IWorkbench;
40 import org.eclipse.ui.IWorkbenchPage;
41 import org.eclipse.ui.IWorkbenchPreferenceConstants;
42 import org.eclipse.ui.IWorkbenchWindow;
43 import org.eclipse.ui.IWorkingSet;
44 import org.eclipse.ui.PlatformUI;
45 import org.eclipse.ui.WorkbenchException;
46 import org.eclipse.ui.activities.IActivityManager;
47 import org.eclipse.ui.activities.IIdentifier;
48 import org.eclipse.ui.activities.IWorkbenchActivitySupport;
49 import org.eclipse.ui.activities.WorkbenchActivityHelper;
50 import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
51 import org.eclipse.ui.ide.IDE;
52 import org.eclipse.ui.ide.undo.CreateProjectOperation;
53 import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
54 import org.eclipse.ui.internal.IPreferenceConstants;
55 import org.eclipse.ui.internal.WorkbenchPlugin;
56 import org.eclipse.ui.internal.ide.IDEInternalPreferences;
57 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
58 import org.eclipse.ui.internal.ide.StatusUtil;
59 import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
60 import org.eclipse.ui.internal.util.PrefUtil;
61 import org.eclipse.ui.internal.wizards.newresource.ResourceMessages;
62 import org.eclipse.ui.statushandlers.StatusAdapter;
63 import org.eclipse.ui.statushandlers.StatusManager;
64 import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard;
65 import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
67 import net.mograsim.plugin.nature.AddMograsimNatureHandler;
70 * This is a copy of {@link BasicNewProjectResourceWizard} for Mograsim. (This is done to remove the reference tab)
73 * @author Christian Femers
76 public class NewMograsimProject extends BasicNewResourceWizard implements IExecutableExtension
79 private WizardNewProjectCreationPage mainPage;
80 private MograsimSettingsPage mograsimPage;
82 // cache of newly-created project
83 private IProject newProject;
86 * The config element which declares this wizard.
88 private IConfigurationElement configElement;
90 private static String WINDOW_PROBLEMS_TITLE = ResourceMessages.NewProject_errorOpeningWindow;
93 * Extension attribute name for final perspective.
95 private static final String FINAL_PERSPECTIVE = "finalPerspective"; //$NON-NLS-1$
98 * Extension attribute name for preferred perspectives.
100 private static final String PREFERRED_PERSPECTIVES = "preferredPerspectives"; //$NON-NLS-1$
103 * Creates a wizard for creating a new project resource in the workspace.
105 public NewMograsimProject()
107 IDialogSettings workbenchSettings = IDEWorkbenchPlugin.getDefault().getDialogSettings();
108 IDialogSettings section = workbenchSettings.getSection("BasicNewProjectResourceWizard");//$NON-NLS-1$
111 section = workbenchSettings.addNewSection("BasicNewProjectResourceWizard");//$NON-NLS-1$
113 setDialogSettings(section);
118 public void addPages()
122 mainPage = new WizardNewProjectCreationPage("basicNewProjectPage") //$NON-NLS-1$
125 public void createControl(Composite parent)
127 super.createControl(parent);
128 createWorkingSetGroup((Composite) getControl(), getSelection(), new String[] { "org.eclipse.ui.resourceWorkingSetPage" }); //$NON-NLS-1$
129 Dialog.applyDialogFont(getControl());
132 mainPage.setTitle("New Mograsim Project");
133 mainPage.setDescription(ResourceMessages.NewProject_description);
134 this.addPage(mainPage);
136 mograsimPage = new MograsimSettingsPage()
139 public void createControl(Composite parent)
141 super.createControl(parent);
142 Dialog.applyDialogFont(getControl());
145 mograsimPage.setDescription("Configure the Mograsim Project and its Machine");
146 this.addPage(mograsimPage);
150 * Creates a new project resource with the selected name.
152 * In normal usage, this method is invoked after the user has pressed Finish on the wizard; the enablement of the Finish button implies
153 * that all controls on the pages currently contain valid values.
156 * Note that this wizard caches the new project once it has been successfully created; subsequent invocations of this method will answer
157 * the same project resource without attempting to create it again.
160 * @return the created project resource, or <code>null</code> if the project was not created
162 private IProject createNewProject()
164 if (newProject != null)
169 // get a project handle
170 final IProject newProjectHandle = mainPage.getProjectHandle();
172 // get a project descriptor
174 if (!mainPage.useDefaults())
176 location = mainPage.getLocationURI();
179 IWorkspace workspace = ResourcesPlugin.getWorkspace();
180 final IProjectDescription description = workspace.newProjectDescription(newProjectHandle.getName());
181 description.setLocationURI(location);
183 // create the new project operation
184 IRunnableWithProgress op = monitor ->
186 CreateProjectOperation op1 = new CreateProjectOperation(description, ResourceMessages.NewProject_windowTitle);
189 // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=219901
190 // directly execute the operation so that the undo state is
191 // not preserved. Making this undoable resulted in too many
192 // accidental file deletions.
193 op1.execute(monitor, WorkspaceUndoUtil.getUIInfoAdapter(getShell()));
195 catch (ExecutionException e)
197 throw new InvocationTargetException(e);
201 // run the new project creation operation
204 getContainer().run(true, true, op);
206 catch (InterruptedException e)
210 catch (InvocationTargetException e)
212 Throwable t = e.getTargetException();
213 if (t instanceof ExecutionException && t.getCause() instanceof CoreException)
215 CoreException cause = (CoreException) t.getCause();
216 StatusAdapter status;
217 if (cause.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS)
219 status = new StatusAdapter(StatusUtil.newStatus(IStatus.WARNING,
220 NLS.bind(ResourceMessages.NewProject_caseVariantExistsError, newProjectHandle.getName()), cause));
223 status = new StatusAdapter(
224 StatusUtil.newStatus(cause.getStatus().getSeverity(), ResourceMessages.NewProject_errorMessage, cause));
226 status.setProperty(StatusAdapter.TITLE_PROPERTY, ResourceMessages.NewProject_errorMessage);
227 StatusManager.getManager().handle(status, StatusManager.BLOCK);
230 StatusAdapter status = new StatusAdapter(new Status(IStatus.WARNING, IDEWorkbenchPlugin.IDE_WORKBENCH, 0,
231 NLS.bind(ResourceMessages.NewProject_internalError, t.getMessage()), t));
232 status.setProperty(StatusAdapter.TITLE_PROPERTY, ResourceMessages.NewProject_errorMessage);
233 StatusManager.getManager().handle(status, StatusManager.LOG | StatusManager.BLOCK);
238 newProject = newProjectHandle;
244 * Returns the newly created project.
246 * @return the created project, or <code>null</code> if project not created
248 public IProject getNewProject()
254 public void init(IWorkbench workbench, IStructuredSelection currentSelection)
256 super.init(workbench, currentSelection);
257 setNeedsProgressMonitor(true);
258 setWindowTitle("New Mograsim Project");
262 protected void initializeDefaultPageImageDescriptor()
264 ImageDescriptor desc = IDEWorkbenchPlugin.getIDEImageDescriptor("wizban/newprj_wiz.png");//$NON-NLS-1$
265 setDefaultPageImageDescriptor(desc);
268 private static void openInNewWindow(IPerspectiveDescriptor desc)
274 PlatformUI.getWorkbench().openWorkbenchWindow(desc.getId(), ResourcesPlugin.getWorkspace().getRoot());
276 catch (WorkbenchException e)
278 IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
281 ErrorDialog.openError(window.getShell(), WINDOW_PROBLEMS_TITLE, e.getMessage(), e.getStatus());
287 public boolean performFinish()
291 if (newProject == null)
296 IWorkingSet[] workingSets = mainPage.getSelectedWorkingSets();
297 getWorkbench().getWorkingSetManager().addToWorkingSets(newProject, workingSets);
301 AddMograsimNatureHandler.addNatureAndConfigure(getNewProject(), mograsimPage.getMograsimProjectConfig().getMachineId());
303 catch (CoreException e)
309 selectAndReveal(newProject);
314 private static void replaceCurrentPerspective(IPerspectiveDescriptor persp)
317 // Get the active page.
318 IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
323 IWorkbenchPage page = window.getActivePage();
329 // Set the perspective.
330 page.setPerspective(persp);
334 * Stores the configuration element for the wizard. The config element will be used in <code>performFinish</code> to set the result
338 public void setInitializationData(IConfigurationElement cfig, String propertyName, Object data)
340 configElement = cfig;
344 * Updates the perspective for the active page within the window.
346 protected void updatePerspective()
348 updatePerspective(configElement);
352 * Updates the perspective based on the current settings in the Workbench/Perspectives preference page.
354 * Use the setting for the new perspective opening if we are set to open in a new perspective.
356 * A new project wizard class will need to implement the <code>IExecutableExtension</code> interface so as to gain access to the
357 * wizard's <code>IConfigurationElement</code>. That is the configuration element to pass into this method.
360 * @param configElement - the element we are updating with
362 * @see IPreferenceConstants#OPM_NEW_WINDOW
363 * @see IPreferenceConstants#OPM_ACTIVE_PAGE
364 * @see IWorkbenchPreferenceConstants#NO_NEW_PERSPECTIVE
366 public static void updatePerspective(IConfigurationElement configElement)
368 // Do not change perspective if the configuration element is
370 if (configElement == null)
375 // Retrieve the new project open perspective preference setting
376 String perspSetting = PrefUtil.getAPIPreferenceStore().getString(IDE.Preferences.PROJECT_OPEN_NEW_PERSPECTIVE);
378 String promptSetting = IDEWorkbenchPlugin.getDefault().getPreferenceStore()
379 .getString(IDEInternalPreferences.PROJECT_SWITCH_PERSP_MODE);
381 // Return if do not switch perspective setting and are not prompting
382 if (!(promptSetting.equals(MessageDialogWithToggle.PROMPT))
383 && perspSetting.equals(IWorkbenchPreferenceConstants.NO_NEW_PERSPECTIVE))
388 // Read the requested perspective id to be opened.
389 String finalPerspId = configElement.getAttribute(FINAL_PERSPECTIVE);
390 if (finalPerspId == null)
395 // Map perspective id to descriptor.
396 IPerspectiveRegistry reg = PlatformUI.getWorkbench().getPerspectiveRegistry();
398 // leave this code in - the perspective of a given project may map to
399 // activities other than those that the wizard itself maps to.
400 IPerspectiveDescriptor finalPersp = reg.findPerspectiveWithId(finalPerspId);
401 if (finalPersp != null && finalPersp instanceof IPluginContribution)
403 IPluginContribution contribution = (IPluginContribution) finalPersp;
404 if (contribution.getPluginId() != null)
406 IWorkbenchActivitySupport workbenchActivitySupport = PlatformUI.getWorkbench().getActivitySupport();
407 IActivityManager activityManager = workbenchActivitySupport.getActivityManager();
408 IIdentifier identifier = activityManager.getIdentifier(WorkbenchActivityHelper.createUnifiedId(contribution));
409 Set<String> idActivities = identifier.getActivityIds();
411 if (!idActivities.isEmpty())
413 Set<String> enabledIds = new HashSet<>(activityManager.getEnabledActivityIds());
415 if (enabledIds.addAll(idActivities))
417 workbenchActivitySupport.setEnabledActivityIds(enabledIds);
423 IDEWorkbenchPlugin.log("Unable to find persective " //$NON-NLS-1$
424 + finalPerspId + " in BasicNewProjectResourceWizard.updatePerspective"); //$NON-NLS-1$
428 // gather the preferred perspectives
429 // always consider the final perspective (and those derived from it)
431 ArrayList<String> preferredPerspIds = new ArrayList<>();
432 addPerspectiveAndDescendants(preferredPerspIds, finalPerspId);
433 String preferred = configElement.getAttribute(PREFERRED_PERSPECTIVES);
434 if (preferred != null)
436 StringTokenizer tok = new StringTokenizer(preferred, " \t\n\r\f,"); //$NON-NLS-1$
437 while (tok.hasMoreTokens())
439 addPerspectiveAndDescendants(preferredPerspIds, tok.nextToken());
443 IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
446 IWorkbenchPage page = window.getActivePage();
449 IPerspectiveDescriptor currentPersp = page.getPerspective();
451 // don't switch if the current perspective is a preferred
453 if (currentPersp != null && preferredPerspIds.contains(currentPersp.getId()))
459 // prompt the user to switch
460 if (!confirmPerspectiveSwitch(window, finalPersp))
466 int workbenchPerspectiveSetting = WorkbenchPlugin.getDefault().getPreferenceStore().getInt(IPreferenceConstants.OPEN_PERSP_MODE);
468 // open perspective in new window setting
469 if (workbenchPerspectiveSetting == IPreferenceConstants.OPM_NEW_WINDOW)
471 openInNewWindow(finalPersp);
475 // replace active perspective setting otherwise
476 replaceCurrentPerspective(finalPersp);
480 * Adds to the list all perspective IDs in the Workbench who's original ID matches the given ID.
482 * @param perspectiveIds the list of perspective IDs to supplement.
483 * @param id the id to query.
486 private static void addPerspectiveAndDescendants(List<String> perspectiveIds, String id)
488 IPerspectiveRegistry registry = PlatformUI.getWorkbench().getPerspectiveRegistry();
489 for (IPerspectiveDescriptor perspective : registry.getPerspectives())
491 // @issue illegal ref to workbench internal class;
492 // consider adding getOriginalId() as API on IPerspectiveDescriptor
493 PerspectiveDescriptor descriptor = ((PerspectiveDescriptor) perspective);
494 if (descriptor.getOriginalId().equals(id))
496 perspectiveIds.add(descriptor.getId());
502 * Prompts the user for whether to switch perspectives.
504 * @param window The workbench window in which to switch perspectives; must not be <code>null</code>
505 * @param finalPersp The perspective to switch to; must not be <code>null</code>.
507 * @return <code>true</code> if it's OK to switch, <code>false</code> otherwise
509 private static boolean confirmPerspectiveSwitch(IWorkbenchWindow window, IPerspectiveDescriptor finalPersp)
511 IPreferenceStore store = IDEWorkbenchPlugin.getDefault().getPreferenceStore();
512 String pspm = store.getString(IDEInternalPreferences.PROJECT_SWITCH_PERSP_MODE);
513 if (!IDEInternalPreferences.PSPM_PROMPT.equals(pspm))
515 // Return whether or not we should always switch
516 return IDEInternalPreferences.PSPM_ALWAYS.equals(pspm);
518 String desc = finalPersp.getDescription();
520 if (desc == null || desc.length() == 0)
521 message = NLS.bind(ResourceMessages.NewProject_perspSwitchMessage, finalPersp.getLabel());
523 message = NLS.bind(ResourceMessages.NewProject_perspSwitchMessageWithDesc, new String[] { finalPersp.getLabel(), desc });
525 LinkedHashMap<String, Integer> buttonLabelToId = new LinkedHashMap<>();
526 buttonLabelToId.put(ResourceMessages.NewProject_perspSwitchButtonLabel, IDialogConstants.YES_ID);
527 buttonLabelToId.put(IDialogConstants.NO_LABEL, IDialogConstants.NO_ID);
528 MessageDialogWithToggle dialog = MessageDialogWithToggle.open(MessageDialog.QUESTION, window.getShell(),
529 ResourceMessages.NewProject_perspSwitchTitle, message, null, false, store, IDEInternalPreferences.PROJECT_SWITCH_PERSP_MODE,
530 SWT.NONE, buttonLabelToId);
531 int result = dialog.getReturnCode();
533 // If we are not going to prompt anymore propogate the choice.
534 if (dialog.getToggleState())
536 String preferenceValue;
537 if (result == IDialogConstants.YES_ID)
539 // Doesn't matter if it is replace or new window
540 // as we are going to use the open perspective setting
541 preferenceValue = IWorkbenchPreferenceConstants.OPEN_PERSPECTIVE_REPLACE;
544 preferenceValue = IWorkbenchPreferenceConstants.NO_NEW_PERSPECTIVE;
547 // update PROJECT_OPEN_NEW_PERSPECTIVE to correspond
548 PrefUtil.getAPIPreferenceStore().setValue(IDE.Preferences.PROJECT_OPEN_NEW_PERSPECTIVE, preferenceValue);
550 return result == IDialogConstants.YES_ID;