package com.redhat.ceylon.eclipse.code.preferences; import java.lang.reflect.InvocationTargetException; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.actions.WorkbenchRunnableAdapter; import org.eclipse.jdt.internal.ui.dialogs.StatusUtil; import org.eclipse.jdt.internal.ui.preferences.PreferencesMessages; import org.eclipse.jdt.internal.ui.util.ExceptionHandler; import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.preference.IPreferencePageContainer; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.PropertyPage; import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer; import com.redhat.ceylon.eclipse.core.builder.CeylonBuilder; import com.redhat.ceylon.eclipse.core.builder.CeylonNature; import com.redhat.ceylon.eclipse.ui.CeylonPlugin; public class CeylonBuildPathsPropertiesPage extends PropertyPage implements IStatusChangeListener { public static final String ID = CeylonPlugin.PLUGIN_ID + ".preferences.paths"; private static final String PAGE_SETTINGS = "BuildPathsPropertyPage"; private static final String INDEX = "pageIndex"; private boolean fBlockOnApply = false; private CeylonBuildPathsBlock fBuildPathsBlock; public void statusChanged(IStatus status) { setValid(!status.matches(IStatus.ERROR)); StatusUtil.applyToStatusLine(this, status); } @Override public boolean performOk() { if (fBuildPathsBlock != null) { getSettings().put(INDEX, fBuildPathsBlock.getPageIndex()); boolean overwriteCeylonConfig = false; if (!fBuildPathsBlock.wasInSyncWithCeylonConfigWhenOpening() && !fBuildPathsBlock.isInSyncWithCeylonConfig()) { if (!MessageDialog.openQuestion(getShell(), "Setting Ceylon Build Path", "The Ceylon configuration file (.ceylon/config) is not synchronized with the current build path settings.\n" + "Do you want to overwrite the configuration file with the settings defined here ?")) { return false; } overwriteCeylonConfig = true; } if (fBuildPathsBlock.hasChangesInDialog() || fBuildPathsBlock.isClassfileMissing() || overwriteCeylonConfig) { IWorkspaceRunnable runnable= new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException, OperationCanceledException { fBuildPathsBlock.configureJavaProject(monitor); } }; WorkbenchRunnableAdapter op= new WorkbenchRunnableAdapter(runnable); if (fBlockOnApply) { try { new ProgressMonitorDialog(getShell()).run(true, true, op); } catch (InvocationTargetException e) { ExceptionHandler.handle(e, getShell(), PreferencesMessages.BuildPathsPropertyPage_error_title, PreferencesMessages.BuildPathsPropertyPage_error_message); return false; } catch (InterruptedException e) { return false; } } else { op.runAsUserJob(PreferencesMessages.BuildPathsPropertyPage_job_title, null); } } } return true; } @Override protected Control createContents(Composite parent) { // ensure the page has no special buttons noDefaultAndApplyButton(); IProject project = getProject(); Control result; if (project == null) { result = createWithoutCeylon(parent); } else if (!project.isOpen()) { result = createForClosedProject(parent); } else if (!isCeylonProject(project)) { result = createWithoutCeylon(parent); } else { result = createWithCeylon(parent, project); } Dialog.applyDialogFont(result); return result; } /* * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) */ @Override public void createControl(Composite parent) { super.createControl(parent); PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaHelpContextIds.BUILD_PATH_PROPERTY_PAGE); } private IDialogSettings getSettings() { IDialogSettings javaSettings = CeylonPlugin.getInstance().getDialogSettings(); IDialogSettings pageSettings = javaSettings.getSection(PAGE_SETTINGS); if (pageSettings == null) { pageSettings = javaSettings.addNewSection(PAGE_SETTINGS); pageSettings.put(INDEX, 1); } return pageSettings; } @Override public boolean okToLeave() { if (fBuildPathsBlock != null && fBuildPathsBlock.hasChangesInDialog()) { String title = PreferencesMessages.BuildPathsPropertyPage_unsavedchanges_title; String message = PreferencesMessages.BuildPathsPropertyPage_unsavedchanges_message; String[] buttonLabels = new String[] { PreferencesMessages.BuildPathsPropertyPage_unsavedchanges_button_save, PreferencesMessages.BuildPathsPropertyPage_unsavedchanges_button_discard, PreferencesMessages.BuildPathsPropertyPage_unsavedchanges_button_ignore }; MessageDialog dialog= new MessageDialog(getShell(), title, null, message, MessageDialog.QUESTION, buttonLabels, 0); int res= dialog.open(); if (res == 0) { //save fBlockOnApply= true; return performOk() && super.okToLeave(); } else if (res == 1) { // discard fBuildPathsBlock.init(JavaCore.create(getProject()), null, null, CeylonBuilder.compileToJava(getProject())); } else { // keep unsaved } } return super.okToLeave(); } @Override public void setVisible(boolean visible) { if (fBuildPathsBlock != null) { if (visible) { if (!fBuildPathsBlock.hasChangesInDialog() && fBuildPathsBlock.hasChangesInClasspathFile()) { fBuildPathsBlock.init(JavaCore.create(getProject()), null, null, CeylonBuilder.compileToJava(getProject())); } } } super.setVisible(visible); } /* * Content for valid projects. */ private Control createWithCeylon(Composite parent, IProject project) { IWorkbenchPreferenceContainer pageContainer= null; IPreferencePageContainer container= getContainer(); if (container instanceof IWorkbenchPreferenceContainer) { pageContainer= (IWorkbenchPreferenceContainer) container; } fBuildPathsBlock= new CeylonBuildPathsBlock(this, getSettings().getInt(INDEX), pageContainer); fBuildPathsBlock.init(JavaCore.create(project), null, null, CeylonBuilder.compileToJava(project)); return fBuildPathsBlock.createControl(parent); } /* * Content for non-Java projects. */ private Control createWithoutCeylon(Composite parent) { Label label = new Label(parent, SWT.LEFT); label.setText("Not a Ceylon project"); fBuildPathsBlock= null; setValid(true); return label; } /* * Content for closed projects. */ private Control createForClosedProject(Composite parent) { Label label= new Label(parent, SWT.LEFT); label.setText("Information not available for closed project."); fBuildPathsBlock= null; setValid(true); return label; } private IProject getProject() { IAdaptable adaptable = getElement(); return adaptable == null ? null : (IProject) adaptable.getAdapter(IProject.class); } private boolean isCeylonProject(IProject proj) { try { return proj.hasNature(JavaCore.NATURE_ID) && proj.hasNature(CeylonNature.NATURE_ID); } catch (CoreException e) { JavaPlugin.log(e); } return false; } }