package com.redhat.ceylon.eclipse.code.preferences; import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.areAstAwareIncrementalBuildsEnabled; import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.compileToJava; import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.compileToJs; import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.getCeylonSystemRepo; import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.getVerbose; import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.isExplodeModulesEnabled; import static com.redhat.ceylon.eclipse.java2ceylon.Java2CeylonProxies.modelJ2C; import static com.redhat.ceylon.eclipse.util.InteropUtils.toJavaBoolean; import static com.redhat.ceylon.eclipse.util.InteropUtils.toJavaString; import static org.eclipse.core.resources.ResourcesPlugin.getWorkspace; import static org.eclipse.jface.layout.GridDataFactory.swtDefaults; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.runtime.CoreException; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.PropertyPage; import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer; import com.redhat.ceylon.eclipse.core.builder.CeylonNature; import com.redhat.ceylon.eclipse.ui.CeylonPlugin; import com.redhat.ceylon.eclipse.ui.CeylonResources; import com.redhat.ceylon.ide.common.model.CeylonProjectConfig; public class CeylonProjectPropertiesPage extends PropertyPage { private boolean explodeModules = true; private boolean builderEnabled = false; private boolean backendJs = false; private boolean backendJava = false; private boolean astAwareIncrementalBuids = true; private Boolean offlineOption = null; private String verbose = null; private Button compileToJs; private Button astAwareIncrementalBuidsButton; private Button compileToJava; private Button offlineButton; private Combo verboseText; private Button enableBuilderButton; private IResourceChangeListener encodingListener; private Text jdkProviderText; private String jdkProvider; @Override public boolean performOk() { store(); return true; } @Override protected void performDefaults() { explodeModules=true; backendJs = false; backendJava = true; compileToJs.setSelection(false); compileToJava.setSelection(true); astAwareIncrementalBuidsButton.setSelection(true); offlineOption = null; verboseText = null; jdkProvider = null; jdkProviderText.setText(""); super.performDefaults(); } private void store() { IProject project = getSelectedProject(); if (CeylonNature.isEnabled(project)) { String systemRepo = getCeylonSystemRepo(project); new CeylonNature(systemRepo, explodeModules, backendJava, backendJs, astAwareIncrementalBuids, verbose) .addToProject(project); CeylonProjectConfig config = modelJ2C().ceylonModel() .getProject(project) .getConfiguration(); if (offlineOption!=null) { config.setProjectOffline(ceylon.language.Boolean.instance(offlineOption)); } String jdkProvider = jdkProviderText.getText().trim(); config.setProjectJdkProvider(jdkProvider.isEmpty() ? null : ceylon.language.String.instance(jdkProvider)); config.save(); } } private IProject getSelectedProject() { return (IProject) getElement().getAdapter(IProject.class); } void addControls(final Composite parent) { Label desc = new Label(parent, SWT.LEFT | SWT.WRAP); desc.setText("The Ceylon builder compiles Ceylon source contained in the project."); enableBuilderButton = new Button(parent, SWT.PUSH); enableBuilderButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER)); enableBuilderButton.setText("Enable Ceylon Builder"); enableBuilderButton.setEnabled(!builderEnabled && getSelectedProject().isOpen()); enableBuilderButton.setImage(CeylonPlugin.imageRegistry().get(CeylonResources.ELE32)); //enableBuilder.setSize(40, 40); Label sep = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); GridData sgd = new GridData(GridData.HORIZONTAL_ALIGN_FILL); sep.setLayoutData(sgd); Composite composite = new Composite(parent, SWT.NONE); GridData gdb = new GridData(GridData.HORIZONTAL_ALIGN_FILL); gdb.grabExcessHorizontalSpace=true; composite.setLayoutData(gdb); GridLayout layoutb = new GridLayout(); layoutb.numColumns = 1; layoutb.marginBottom = 1; composite.setLayout(layoutb); addCharacterEncodingLabel(composite); offlineButton = new Button(composite, SWT.CHECK); offlineButton.setText("Work offline (disable connection to remote module repositories)"); offlineButton.setEnabled(builderEnabled); offlineButton.setSelection(offlineOption!=null&&offlineOption); offlineButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { if (offlineOption == null) { offlineOption = true; } else { offlineOption = !offlineOption; } } }); final Group platformGroup = new Group(parent, SWT.NONE); platformGroup.setText("Target virtual machine"); GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL); gd.grabExcessHorizontalSpace=true; platformGroup.setLayoutData(gd); GridLayout layout = new GridLayout(); layout.numColumns = 1; layout.marginBottom = 1; platformGroup.setLayout(layout); compileToJava = new Button(platformGroup, SWT.CHECK); compileToJava.setText("Compile project for JVM"); compileToJava.setSelection(backendJava); compileToJava.setEnabled(builderEnabled); compileToJs = new Button(platformGroup, SWT.CHECK); compileToJs.setText("Compile project to JavaScript"); compileToJs.setSelection(backendJs); compileToJs.setEnabled(builderEnabled); initJdkProvider(parent); Group troubleGroup = new Group(parent, SWT.NONE); troubleGroup.setText("Troubleshooting"); troubleGroup.setLayout(new GridLayout(1, false)); GridData gd3 = new GridData(GridData.HORIZONTAL_ALIGN_FILL); gd3.grabExcessHorizontalSpace=true; troubleGroup.setLayoutData(gd3); astAwareIncrementalBuidsButton = new Button(troubleGroup, SWT.CHECK); astAwareIncrementalBuidsButton.setText("Disable structure-aware incremental compilation"); astAwareIncrementalBuidsButton.setSelection(!astAwareIncrementalBuids); astAwareIncrementalBuidsButton.setEnabled(builderEnabled); final Button logButton = new Button(troubleGroup, SWT.CHECK); logButton.setText("Log compiler activity to Eclipse console"); boolean loggingEnabled = verbose!=null && !verbose.isEmpty(); logButton.setSelection(loggingEnabled); logButton.setEnabled(builderEnabled); final Composite verbosityOptions = new Composite(troubleGroup, SWT.NONE); verbosityOptions.setLayout(new GridLayout(2, false)); final GridData gd4 = new GridData(GridData.HORIZONTAL_ALIGN_FILL); gd4.grabExcessHorizontalSpace=true; verbosityOptions.setLayoutData(gd4); gd4.exclude = !loggingEnabled; verbosityOptions.setVisible(loggingEnabled); verbosityOptions.setEnabled(loggingEnabled); final Label verbosityLabel = new Label(verbosityOptions, SWT.NONE); verbosityLabel.setText("Verbosity level"); verboseText = new Combo(verbosityOptions, SWT.DROP_DOWN); verboseText.add("code"); verboseText.add("ast"); verboseText.add("loader"); verboseText.add("cmr"); verboseText.add("all"); GridData vgd = new GridData(); vgd.grabExcessHorizontalSpace = true; vgd.minimumWidth = 75; verboseText.setLayoutData(vgd); verboseText.setTextLimit(20); if (loggingEnabled) { verboseText.setText(verbose); } verboseText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { String str = verboseText.getText(); if (str==null || str.isEmpty()) { verbose = null; } else { verbose = str.trim(); } } }); logButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { boolean selected = logButton.getSelection(); verbose = selected ? verboseText.getText() : null; verboseText.setEnabled(selected); ((GridData) verbosityOptions.getLayoutData()).exclude = !selected; verbosityOptions.setVisible(selected); verbosityOptions.setEnabled(selected); verboseText.setVisible(selected); parent.layout(); } }); enableBuilderButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { new CeylonNature().addToProject(getSelectedProject()); enableBuilderButton.setEnabled(false); astAwareIncrementalBuidsButton.setEnabled(true); compileToJs.setEnabled(true); compileToJava.setEnabled(true); offlineButton.setEnabled(true); logButton.setEnabled(true); builderEnabled=true; } }); astAwareIncrementalBuidsButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { astAwareIncrementalBuids = !astAwareIncrementalBuids; } }); compileToJava.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { backendJava = !backendJava; } }); compileToJs.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { backendJs = !backendJs; } }); Link buildPathsPageLink = new Link(parent, 0); buildPathsPageLink.setText("See '<a>Build Paths</a>' to configure project build paths."); buildPathsPageLink.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { IWorkbenchPreferenceContainer container = (IWorkbenchPreferenceContainer) getContainer(); container.openPage(CeylonBuildPathsPropertiesPage.ID, null); } }); Link openRepoPageLink = new Link(parent, 0); openRepoPageLink.setText("See '<a>Module Repositories</a>' to configure project module repositores."); openRepoPageLink.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { IWorkbenchPreferenceContainer container = (IWorkbenchPreferenceContainer) getContainer(); container.openPage(CeylonRepoPropertiesPage.ID, null); } }); Link warningsPageLink = new Link(parent, 0); warningsPageLink.setText("See '<a>Warnings</a>' to enable or disable warnings."); warningsPageLink.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { IWorkbenchPreferenceContainer container = (IWorkbenchPreferenceContainer) getContainer(); container.openPage(CeylonWarningsPropertiesPage.ID, null); } }); } private void addCharacterEncodingLabel(Composite composite) { final Link link = new Link(composite, SWT.NONE); try { link.setText("Default source file encoding: " + getSelectedProject().getDefaultCharset() + " <a>(Change...)</a>"); link.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { IWorkbenchPreferenceContainer container = (IWorkbenchPreferenceContainer) getContainer(); container.openPage("org.eclipse.ui.propertypages.info.file", null); } }); getWorkspace().addResourceChangeListener(encodingListener=new IResourceChangeListener() { @Override public void resourceChanged(IResourceChangeEvent event) { if (event.getType()==IResourceChangeEvent.POST_CHANGE) { Display.getDefault().asyncExec(new Runnable() { public void run() { try { if (!link.isDisposed()) { link.setText("Default source file encoding: " + getSelectedProject().getDefaultCharset() + " <a>(Change...)</a>"); } } catch (CoreException e) { e.printStackTrace(); } } }); } } }); } catch (CoreException e) { e.printStackTrace(); } } @Override protected Control createContents(Composite composite) { IProject project = getSelectedProject(); if (project.isOpen()) { builderEnabled = CeylonNature.isEnabled(project); if (builderEnabled) { astAwareIncrementalBuids = areAstAwareIncrementalBuildsEnabled(project); explodeModules = isExplodeModulesEnabled(project); backendJs = compileToJs(project); backendJava = compileToJava(project); verbose = getVerbose(project); offlineOption = toJavaBoolean(modelJ2C().ceylonModel().getProject(project).getConfiguration().getProjectOffline()); jdkProvider = toJavaString(modelJ2C().ceylonModel().getProject(project).getConfiguration().getProjectJdkProvider()); } } addControls(composite); return composite; } @Override public void dispose() { if (encodingListener!=null) { getWorkspace().removeResourceChangeListener(encodingListener); encodingListener = null; } super.dispose(); } private void initJdkProvider(Composite parent) { Group jdkProviderGroup = new Group(parent, SWT.NONE); GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL); gd.grabExcessHorizontalSpace=true; jdkProviderGroup.setLayoutData(gd); GridLayout layout = new GridLayout(); layout.numColumns = 1; layout.marginBottom = 1; jdkProviderGroup.setLayout(layout); jdkProviderGroup.setText("JDK provider"); jdkProviderText = new Text(jdkProviderGroup, SWT.SINGLE | SWT.BORDER); jdkProviderText.setLayoutData(swtDefaults() .align(SWT.FILL, SWT.CENTER) .grab(true, false) .create()); jdkProviderText.setMessage("Default JDK provider"); if(jdkProvider != null) jdkProviderText.setText(jdkProvider); } }