| /*=============================================================================# |
| # Copyright (c) 2009, 2018 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.internal.r.ui; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.core.databinding.UpdateValueStrategy; |
| import org.eclipse.core.databinding.observable.Realm; |
| import org.eclipse.core.databinding.observable.list.WritableList; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jface.resource.JFaceResources; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.TabFolder; |
| import org.eclipse.swt.widgets.TabItem; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.ISharedImages; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.statushandlers.StatusManager; |
| |
| import org.eclipse.statet.jcommons.collections.ImList; |
| |
| import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport; |
| import org.eclipse.statet.ecommons.preferences.core.Preference; |
| import org.eclipse.statet.ecommons.preferences.ui.ConfigurationBlock; |
| import org.eclipse.statet.ecommons.preferences.ui.ManagedConfigurationBlock; |
| import org.eclipse.statet.ecommons.preferences.ui.PropertyAndPreferencePage; |
| import org.eclipse.statet.ecommons.runtime.core.StatusChangeListener; |
| import org.eclipse.statet.ecommons.ui.util.LayoutUtil; |
| |
| import org.eclipse.statet.internal.r.ui.buildpaths.RBuildpathsUIDescription; |
| import org.eclipse.statet.ltk.buildpaths.core.IBuildpathElement; |
| import org.eclipse.statet.ltk.buildpaths.ui.SourceContainerComponent; |
| import org.eclipse.statet.r.core.IRProject; |
| import org.eclipse.statet.r.core.RBuildpaths; |
| import org.eclipse.statet.r.core.RProjects; |
| import org.eclipse.statet.r.ui.RUI; |
| |
| |
| public class RProjectPropertyPage extends PropertyAndPreferencePage { |
| |
| |
| public RProjectPropertyPage() { |
| } |
| |
| |
| @Override |
| protected String getPreferencePageID() { |
| return null; |
| } |
| |
| @Override |
| protected String getPropertyPageID() { |
| return "org.eclipse.statet.r.propertyPages.RProject"; //$NON-NLS-1$ |
| } |
| |
| |
| @Override |
| protected ConfigurationBlock createConfigurationBlock() throws CoreException { |
| return new RProjectConfigurationBlock(getProject(), createStatusChangedListener()); |
| } |
| |
| @Override |
| protected boolean hasProjectSpecificSettings(final IProject project) { |
| return true; |
| } |
| |
| } |
| |
| |
| class RProjectConfigurationBlock extends ManagedConfigurationBlock { |
| |
| |
| private final IRProject rProject; |
| |
| private final RBuildpathsUIDescription buildpathUIDescription; |
| private final WritableList buildpathList; |
| |
| private final SourceContainerComponent sourceFolders; |
| |
| private Text pkgNameControl; |
| |
| private RProjectContainerComposite projectComposite; |
| |
| private REnvSelectionComposite rEnvControl; |
| |
| |
| public RProjectConfigurationBlock(final IProject project, final StatusChangeListener statusListener) { |
| super(project, statusListener); |
| |
| this.rProject= RProjects.getRProject(project); |
| |
| this.buildpathUIDescription= new RBuildpathsUIDescription(); |
| this.buildpathList= new WritableList(); |
| this.sourceFolders= new SourceContainerComponent(buildpathList, |
| RBuildpaths.R_SOURCE_TYPE, null, buildpathUIDescription ); |
| } |
| |
| |
| @Override |
| protected void createBlockArea(final Composite pageComposite) { |
| final Map<Preference<?>, String> prefs= new HashMap<>(); |
| |
| prefs.put(IRProject.BASE_FOLDER_PATH_PREF, null); |
| prefs.put(IRProject.RENV_CODE_PREF, null); |
| |
| setupPreferenceManager(prefs); |
| |
| final Composite mainComposite= new Composite(pageComposite, SWT.NONE); |
| mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| mainComposite.setLayout(LayoutUtil.createCompositeGrid(2)); |
| |
| final TabFolder folder = new TabFolder(mainComposite, SWT.NONE); |
| folder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); |
| |
| { final TabItem item = new TabItem(folder, SWT.NONE); |
| item.setText("&Main"); |
| item.setControl(createMainTab(folder)); |
| } |
| { final TabItem item= new TabItem(folder, SWT.NONE); |
| item.setImage(PlatformUI.getWorkbench().getSharedImages().getImage( |
| ISharedImages.IMG_OBJ_FOLDER )); |
| item.setText("&Source"); |
| item.setControl(createSourceTab(folder)); |
| } |
| { final TabItem item= new TabItem(folder, SWT.NONE); |
| item.setImage(RUI.getImage(RUI.IMG_OBJ_R_RUNTIME_ENV)); |
| item.setText("R &Environment"); |
| item.setControl(createREnvTab(folder)); |
| } |
| |
| initBindings(); |
| updateControls(); |
| } |
| |
| private Control createMainTab(final Composite parent) { |
| final Composite composite= new Composite(parent, SWT.NONE); |
| composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| composite.setLayout(LayoutUtil.createTabGrid(2)); |
| |
| { final Composite packageComposite= new Composite(composite, SWT.NONE); |
| packageComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); |
| packageComposite.setLayout(LayoutUtil.createCompositeGrid(2)); |
| |
| final Label label= new Label(packageComposite, SWT.NONE); |
| label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); |
| label.setText("Package &Name:"); |
| |
| this.pkgNameControl= new Text(packageComposite, SWT.BORDER); |
| this.pkgNameControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); |
| this.pkgNameControl.setFont(JFaceResources.getTextFont()); |
| |
| LayoutUtil.addGDDummy(composite); |
| } |
| |
| this.projectComposite= new RProjectContainerComposite(composite, getProject()); |
| this.projectComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| this.projectComposite.setBackground(this.projectComposite.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); |
| |
| final Composite buttons= new Composite(composite, SWT.NONE); |
| buttons.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); |
| buttons.setLayout(LayoutUtil.createCompositeGrid(1)); |
| |
| final Button setBase= new Button(buttons, SWT.PUSH); |
| setBase.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); |
| setBase.setText("R &Base Folder"); |
| setBase.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(final SelectionEvent e) { |
| RProjectConfigurationBlock.this.projectComposite.toggleBaseContainer(); |
| } |
| }); |
| |
| return composite; |
| } |
| |
| private Control createSourceTab(final Composite parent) { |
| final Composite composite= new Composite(parent, SWT.NONE); |
| composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| composite.setLayout(LayoutUtil.createTabGrid(1)); |
| |
| { final Control control= this.sourceFolders.create(composite); |
| control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| } |
| |
| return composite; |
| } |
| |
| private Control createREnvTab(final Composite parent) { |
| final Composite composite= new Composite(parent, SWT.NONE); |
| composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| composite.setLayout(LayoutUtil.createTabGrid(1)); |
| |
| { final Label label= new Label(composite, SWT.NONE); |
| label.setText("R Envir&onment:"); |
| } |
| this.rEnvControl= new REnvSelectionComposite(composite); |
| this.rEnvControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); |
| |
| return composite; |
| } |
| |
| |
| @Override |
| protected void addBindings(final DataBindingSupport db) { |
| db.getContext().bindValue( |
| this.rEnvControl.createObservable(Realm.getDefault()), |
| createObservable(IRProject.RENV_CODE_PREF), |
| new UpdateValueStrategy().setAfterGetValidator( |
| this.rEnvControl.createValidator(db.getContext()) ), |
| null ); |
| |
| this.sourceFolders.bind(db); |
| } |
| |
| @Override |
| protected void updateControls() { |
| final String value= getPreferenceValue(IRProject.BASE_FOLDER_PATH_PREF); |
| if (value != null) { |
| final IPath basePath= Path.fromPortableString(value); |
| this.projectComposite.setBaseContainer(basePath); |
| } |
| else { |
| this.projectComposite.setBaseContainer(null); |
| } |
| |
| final String packageName= this.rProject.getPackageName(); |
| this.pkgNameControl.setText((packageName != null) ? packageName : ""); //$NON-NLS-1$ |
| |
| { this.buildpathList.clear(); |
| this.buildpathUIDescription.toListElements(getProject(), this.rProject.getRawBuildpath(), |
| this.buildpathList ); |
| this.sourceFolders.init(getProject()); |
| } |
| |
| super.updateControls(); |
| } |
| |
| @Override |
| protected void updatePreferences() { |
| final IPath basePath= this.projectComposite.getBaseContainer(); |
| if (basePath != null) { |
| setPrefValue(IRProject.BASE_FOLDER_PATH_PREF, basePath.toPortableString()); |
| } |
| else { |
| setPrefValue(IRProject.BASE_FOLDER_PATH_PREF, null); |
| } |
| |
| super.updatePreferences(); |
| } |
| |
| @Override |
| public void performApply() { |
| saveProjectConfig(); |
| super.performApply(); |
| } |
| |
| @Override |
| public boolean performOk() { |
| saveProjectConfig(); |
| return super.performOk(); |
| } |
| |
| private void saveProjectConfig() { |
| final ImList<IBuildpathElement> newBuildpath= this.buildpathUIDescription.toCoreElements(this.buildpathList); |
| RBuildpaths.set(getProject(), newBuildpath); |
| try { |
| final String packageName= this.pkgNameControl.getText(); |
| this.rProject.setPackageConfig((packageName.trim().length() != 0) ? packageName : null); |
| } |
| catch (final CoreException e) { |
| StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID, "Failed to apply R project configuration."), StatusManager.SHOW); |
| } |
| } |
| |
| } |