| /*=============================================================================# |
| # Copyright (c) 2017, 2020 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.apps.ui.launching; |
| |
| import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert; |
| |
| import static org.eclipse.statet.ecommons.databinding.core.observable.ObservableUtils.typed; |
| |
| import static org.eclipse.statet.internal.r.apps.ui.launching.AppControlConfigs.VARIABLES_CODE_ATTR_NAME; |
| import static org.eclipse.statet.internal.r.apps.ui.launching.AppControlConfigs.VARIABLES_VIEWER_ACTION_ATTR_NAME; |
| import static org.eclipse.statet.internal.r.apps.ui.launching.AppControlConfigs.VIEWER_ID_ATTR_NAME; |
| |
| import org.eclipse.core.databinding.DataBindingContext; |
| import org.eclipse.core.databinding.observable.Realm; |
| import org.eclipse.core.databinding.observable.value.IObservableValue; |
| import org.eclipse.core.databinding.observable.value.IValueChangeListener; |
| import org.eclipse.core.databinding.observable.value.ValueChangeEvent; |
| import org.eclipse.core.databinding.observable.value.WritableValue; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
| import org.eclipse.jface.databinding.swt.typed.WidgetProperties; |
| import org.eclipse.jface.databinding.viewers.typed.ViewerProperties; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.preference.PreferenceDialog; |
| import org.eclipse.jface.viewers.ArrayContentProvider; |
| import org.eclipse.jface.viewers.ComboViewer; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.StackLayout; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Group; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Link; |
| import org.eclipse.ui.PlatformUI; |
| |
| import org.eclipse.statet.jcommons.collections.ImCollections; |
| import org.eclipse.statet.jcommons.collections.ImList; |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| import org.eclipse.statet.jcommons.lang.Nullable; |
| |
| import org.eclipse.statet.ecommons.debug.ui.config.LaunchConfigTabWithDbc; |
| import org.eclipse.statet.ecommons.templates.TemplateVariableProcessor; |
| import org.eclipse.statet.ecommons.ui.util.LayoutUtils; |
| |
| import org.eclipse.statet.internal.r.apps.ui.Messages; |
| import org.eclipse.statet.ltk.ui.sourceediting.SnippetEditor; |
| import org.eclipse.statet.ltk.ui.sourceediting.SnippetEditor1; |
| import org.eclipse.statet.r.apps.ui.RAppUIResources; |
| import org.eclipse.statet.r.core.RCore; |
| import org.eclipse.statet.r.launching.ui.RLaunchingUI; |
| import org.eclipse.statet.r.ui.sourceediting.RSourceViewerConfigurator; |
| import org.eclipse.statet.r.ui.sourceediting.RTemplateSourceViewerConfigurator; |
| |
| |
| @NonNullByDefault |
| public class AppControlConfigViewTab extends LaunchConfigTabWithDbc |
| implements IValueChangeListener<Object> { |
| |
| |
| static void initDefaults(final ILaunchConfigurationWorkingCopy config) { |
| config.setAttribute(AppControlConfigs.VIEWER_ID_ATTR_NAME, AppControlConfigs.WORKBENCH_VIEW_BROWSER_ID); |
| config.setAttribute(AppControlConfigs.VARIABLES_VIEWER_ACTION_ATTR_NAME, AppControlConfigs.SHOW_ACTION_ID); |
| } |
| |
| |
| private class ViewerItem { |
| |
| |
| private final @Nullable String id; |
| |
| private final String label; |
| |
| private @Nullable Composite detailControl; |
| |
| |
| public ViewerItem(final @Nullable String id, final String label) { |
| this.id= id; |
| this.label= label; |
| } |
| |
| |
| public @Nullable String getId() { |
| return this.id; |
| } |
| |
| @Override // for LabelProvider |
| public String toString() { |
| return this.label; |
| } |
| |
| public @Nullable Composite enable() { |
| Composite control= this.detailControl; |
| if (this.id != null) { |
| if (control == null) { |
| control= createControl(AppControlConfigViewTab.this.viewerDetailControl); |
| this.detailControl= control; |
| } |
| } |
| return control; |
| } |
| |
| public void disable() { |
| } |
| |
| protected Composite createControl(final Composite parent) { |
| final Composite composite= new Composite(parent, SWT.NONE); |
| return composite; |
| } |
| |
| } |
| |
| |
| private ImList<ViewerItem> viewers; |
| |
| private IObservableValue<ViewerItem> viewerValue; |
| |
| private IObservableValue<String> variablesCodeValue; |
| private IObservableValue<Boolean> variablesActionValue; |
| |
| private ComboViewer viewerSelectionViewer; |
| private StackLayout viewerDetailLayout; |
| private Composite viewerDetailControl; |
| |
| private SnippetEditor variablesCodeEditor; |
| private Button variablesActionControl; |
| |
| |
| public AppControlConfigViewTab() { |
| |
| final Realm realm= getRealm(); |
| this.viewerValue= new WritableValue<>(realm, null, String.class); |
| this.viewerValue.addValueChangeListener(this); |
| |
| this.viewers= ImCollections.newList( |
| new ViewerItem(null, Messages.Operation_Viewer_None_label), |
| new ViewerItem(AppControlConfigs.WORKBENCH_VIEW_BROWSER_ID, |
| Messages.Operation_Viewer_WorkbenchView_label), |
| new ViewerItem(AppControlConfigs.WORKBENCH_EXTERNAL_BROWSER_ID, |
| Messages.Operation_Viewer_WorkbenchExternal_label) { |
| @Override |
| protected Composite createControl(final Composite parent) { |
| final Composite composite= super.createControl(parent); |
| |
| composite.setLayout(LayoutUtils.newCompositeGrid(1)); |
| |
| LayoutUtils.addSmallFiller(composite, true); |
| |
| final Link link= new Link(composite, SWT.NONE); |
| link.setText("Global preferences: " |
| + "<a href=\"org.eclipse.ui.browser.preferencePage\">Web Browser</a>."); |
| composite.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false)); |
| link.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(final SelectionEvent e) { |
| final PreferenceDialog dialog= org.eclipse.ui.dialogs.PreferencesUtil.createPreferenceDialogOn(null, e.text, null, null); |
| if (dialog != null) { |
| dialog.open(); |
| } |
| } |
| }); |
| |
| return composite; |
| } |
| }); |
| |
| this.variablesCodeValue= new WritableValue<>(realm, "", String.class); //$NON-NLS-1$ |
| this.variablesActionValue= new WritableValue<>(realm, true, Boolean.TYPE); |
| } |
| |
| |
| @Override |
| public Image getImage() { |
| return nonNullAssert(RAppUIResources.INSTANCE.getImage(RAppUIResources.TOOL_VIEW_IMAGE_ID)); |
| } |
| |
| @Override |
| public String getName() { |
| return Messages.Operation_ViewTab_name; |
| } |
| |
| public String getLabel() { |
| return Messages.Operation_ViewTab_label; |
| } |
| |
| |
| @Override |
| public void createControl(final Composite parent) { |
| final Composite mainComposite= new Composite(parent, SWT.NONE); |
| setControl(mainComposite); |
| mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| mainComposite.setLayout(new GridLayout()); |
| |
| { final Label label= new Label(mainComposite, SWT.NONE); |
| label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); |
| label.setText(getLabel() + ':'); |
| } |
| { final Composite composite= createViewerSettings(mainComposite); |
| composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| } |
| { final Composite composite= createVariablesSettings(mainComposite); |
| composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| } |
| Dialog.applyDialogFont(parent); |
| |
| initBindings(); |
| } |
| |
| |
| private ViewerItem getViewerItem(final String id) { |
| for (final ViewerItem item : this.viewers) { |
| if (item.getId() == id) { |
| return item; |
| } |
| } |
| return this.viewers.get(0); |
| } |
| |
| private Composite createViewerSettings(final Composite parent) { |
| final Group composite= new Group(parent, SWT.NONE); |
| composite.setText(Messages.Operation_ViewTab_Operation_label + ':'); |
| composite.setLayout(LayoutUtils.newGroupGrid(1)); |
| |
| { final ComboViewer viewer= new ComboViewer(composite); |
| |
| viewer.setLabelProvider(new LabelProvider()); |
| viewer.setContentProvider(new ArrayContentProvider()); |
| viewer.setInput(this.viewers); |
| |
| viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); |
| this.viewerSelectionViewer= viewer; |
| } |
| { final Composite detailControl= new Composite(composite, SWT.NONE); |
| |
| this.viewerDetailLayout= new StackLayout(); |
| detailControl.setLayout(this.viewerDetailLayout); |
| |
| detailControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| this.viewerDetailControl= detailControl; |
| } |
| |
| return composite; |
| } |
| |
| private Composite createVariablesSettings(final Composite parent) { |
| final Group composite= new Group(parent, SWT.NONE); |
| composite.setText(Messages.Operation_Variables_label + ':'); |
| composite.setLayout(LayoutUtils.newGroupGrid(2)); |
| |
| { final Label label= new Label(composite, SWT.NONE); |
| label.setText(Messages.Operation_Variables_RCode_label + ':'); |
| label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); |
| |
| final TemplateVariableProcessor templateVariableProcessor= new TemplateVariableProcessor(); |
| final RSourceViewerConfigurator configurator= new RTemplateSourceViewerConfigurator( |
| RCore.getWorkbenchAccess(), |
| templateVariableProcessor ); |
| final SnippetEditor1 editor= new SnippetEditor1(configurator, null, |
| PlatformUI.getWorkbench(), RLaunchingUI.LAUNCH_CONFIG_QUALIFIER ); |
| editor.create(composite, SnippetEditor.DEFAULT_SINGLE_LINE_STYLE); |
| final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, false); |
| gd.heightHint= LayoutUtils.hintHeight(editor.getSourceViewer().getTextWidget(), 1); |
| editor.getControl().setLayoutData(gd); |
| this.variablesCodeEditor= editor; |
| } |
| |
| { final Button button= new Button(composite, SWT.CHECK); |
| button.setText(Messages.Operation_Variables_ShowView_label); |
| |
| button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); |
| this.variablesActionControl= button; |
| } |
| |
| return composite; |
| } |
| |
| |
| @Override |
| protected void addBindings(final DataBindingContext dbc) { |
| dbc.bindValue( |
| ViewerProperties.singleSelection() |
| .observe(this.viewerSelectionViewer), |
| this.viewerValue ); |
| |
| dbc.bindValue( |
| WidgetProperties.text(SWT.Modify) |
| .observe(this.variablesCodeEditor.getTextControl()), |
| this.variablesCodeValue ); |
| dbc.bindValue( |
| WidgetProperties.buttonSelection() |
| .observe(this.variablesActionControl), |
| this.variablesActionValue ); |
| } |
| |
| @Override |
| public void handleValueChange(final ValueChangeEvent<?> event) { |
| if (event.getObservable() == this.viewerValue) { |
| final ViewerItem oldItem= typed(event, this.viewerValue).diff.getOldValue(); |
| if (oldItem != null) { |
| oldItem.disable(); |
| } |
| |
| final ViewerItem newItem= typed(event, this.viewerValue).diff.getNewValue(); |
| if (newItem != null) { |
| this.viewerDetailLayout.topControl= newItem.enable(); |
| } |
| else { |
| this.viewerDetailLayout.topControl= null; |
| } |
| this.viewerDetailControl.layout(); |
| } |
| } |
| |
| |
| @Override |
| public void setDefaults(final ILaunchConfigurationWorkingCopy configuration) { |
| initDefaults(configuration); |
| } |
| |
| @Override |
| protected void doInitialize(final ILaunchConfiguration configuration) { |
| { final String id= readAttribute(configuration, |
| VIEWER_ID_ATTR_NAME, |
| "") //$NON-NLS-1$ |
| .intern(); |
| final ViewerItem item= getViewerItem(id); |
| this.viewerValue.setValue(item); |
| } |
| |
| { final String code= readAttribute(configuration, |
| VARIABLES_CODE_ATTR_NAME, |
| "" ); //$NON-NLS-1$ |
| this.variablesCodeValue.setValue(code); |
| } |
| { final String action= readAttribute(configuration, |
| VARIABLES_VIEWER_ACTION_ATTR_NAME, |
| ""); //$NON-NLS-1$ |
| this.variablesActionValue.setValue(action.equals(AppControlConfigs.SHOW_ACTION_ID)); |
| } |
| } |
| |
| @Override |
| protected void doSave(final ILaunchConfigurationWorkingCopy configuration) { |
| { final ViewerItem item= this.viewerValue.getValue(); |
| configuration.setAttribute(VIEWER_ID_ATTR_NAME, item.getId()); |
| } |
| |
| { final String code= this.variablesCodeValue.getValue(); |
| configuration.setAttribute(VARIABLES_CODE_ATTR_NAME, code); |
| } |
| { final Boolean enabled= this.variablesActionValue.getValue(); |
| configuration.setAttribute(VARIABLES_VIEWER_ACTION_ATTR_NAME, |
| (enabled) ? AppControlConfigs.SHOW_ACTION_ID : null ); |
| } |
| } |
| |
| } |