| /*=============================================================================# |
| # Copyright (c) 2007, 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.preferences; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.core.databinding.UpdateValueStrategy; |
| import org.eclipse.core.databinding.beans.BeanProperties; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.jface.databinding.swt.WidgetProperties; |
| import org.eclipse.swt.SWT; |
| 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.statet.ecommons.databinding.IntegerValidator; |
| import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport; |
| import org.eclipse.statet.ecommons.preferences.core.Preference; |
| import org.eclipse.statet.ecommons.preferences.ui.ManagedConfigurationBlock; |
| import org.eclipse.statet.ecommons.runtime.core.StatusChangeListener; |
| import org.eclipse.statet.ecommons.text.ui.settings.IndentSettingsUI; |
| import org.eclipse.statet.ecommons.ui.util.LayoutUtil; |
| |
| import org.eclipse.statet.r.core.RCodeStyleSettings; |
| |
| |
| /** |
| * A PreferenceBlock for RCodeStyleSettings (code formatting preferences). |
| */ |
| public class RCodeStylePreferenceBlock extends ManagedConfigurationBlock { |
| // in future supporting multiple profiles? |
| // -> we bind to bean not to preferences |
| |
| |
| private RCodeStyleSettings model; |
| |
| private IndentSettingsUI stdIndentSettings; |
| private Text indentBlockDepth; |
| private Text indentGroupDepth; |
| private Text indentWrappedCommandDepth; |
| |
| private Button wsArgAssignBefore; |
| private Button wsArgAssignBehind; |
| private Button nlFDefBodyBlockBefore; |
| |
| |
| public RCodeStylePreferenceBlock(final IProject project, final StatusChangeListener statusListener) { |
| super(project, statusListener); |
| } |
| |
| |
| @Override |
| protected void createBlockArea(final Composite pageComposite) { |
| final Map<Preference<?>, String> prefs= new HashMap<>(); |
| |
| prefs.put(RCodeStyleSettings.INDENT_DEFAULT_TYPE_PREF, RCodeStyleSettings.INDENT_GROUP_ID); |
| prefs.put(RCodeStyleSettings.TAB_SIZE_PREF, RCodeStyleSettings.INDENT_GROUP_ID); |
| prefs.put(RCodeStyleSettings.INDENT_SPACES_COUNT_PREF, RCodeStyleSettings.INDENT_GROUP_ID); |
| prefs.put(RCodeStyleSettings.REPLACE_TABS_WITH_SPACES_PREF, RCodeStyleSettings.INDENT_GROUP_ID); |
| prefs.put(RCodeStyleSettings.REPLACE_CONVERSATIVE_PREF, RCodeStyleSettings.INDENT_GROUP_ID); |
| |
| prefs.put(RCodeStyleSettings.INDENT_BLOCK_DEPTH_PREF, RCodeStyleSettings.INDENT_GROUP_ID); |
| prefs.put(RCodeStyleSettings.INDENT_GROUP_DEPTH_PREF, RCodeStyleSettings.INDENT_GROUP_ID); |
| prefs.put(RCodeStyleSettings.INDENT_WRAPPED_COMMAND_DEPTH_PREF, RCodeStyleSettings.INDENT_GROUP_ID); |
| |
| prefs.put(RCodeStyleSettings.WS_ARGASSIGN_BEFORE_PREF, RCodeStyleSettings.WS_GROUP_ID); |
| prefs.put(RCodeStyleSettings.WS_ARGASSIGN_BEHIND_PREF, RCodeStyleSettings.WS_GROUP_ID); |
| prefs.put(RCodeStyleSettings.NL_FDEF_BODYBLOCK_BEFORE_PREF, RCodeStyleSettings.WS_GROUP_ID); |
| |
| setupPreferenceManager(prefs); |
| |
| this.model= new RCodeStyleSettings(0); |
| this.stdIndentSettings= new IndentSettingsUI(); |
| |
| 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, false, 2, 1)); |
| |
| { final TabItem item= new TabItem(folder, SWT.NONE); |
| item.setText(this.stdIndentSettings.getGroupLabel()); |
| item.setControl(createIndentControls(folder)); |
| } |
| { final TabItem item= new TabItem(folder, SWT.NONE); |
| item.setText("&More"); |
| item.setControl(createMoreControls(folder)); |
| } |
| |
| initBindings(); |
| updateControls(); |
| } |
| |
| private Control createIndentControls(final Composite parent) { |
| final Composite composite= new Composite(parent, SWT.NONE); |
| composite.setLayout(LayoutUtil.createTabGrid(2)); |
| |
| this.stdIndentSettings.createControls(composite); |
| LayoutUtil.addSmallFiller(composite, false); |
| |
| final Composite depthComposite= new Composite(composite, SWT.NONE); |
| depthComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); |
| depthComposite.setLayout(LayoutUtil.createCompositeGrid(3)); |
| this.indentBlockDepth= createIndentDepthLine(depthComposite, Messages.RCodeStyle_Indent_IndentInBlocks_label); |
| this.indentGroupDepth= createIndentDepthLine(depthComposite, Messages.RCodeStyle_Indent_IndentInGroups_label); |
| this.indentWrappedCommandDepth= createIndentDepthLine(depthComposite, Messages.RCodeStyle_Indent_IndentOfWrappedCommands_label); |
| |
| return composite; |
| } |
| |
| private Text createIndentDepthLine(final Composite composite, final String label) { |
| final Label labelControl= new Label(composite, SWT.LEFT); |
| labelControl.setText(label); |
| labelControl.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); |
| final Text textControl= new Text(composite, SWT.RIGHT | SWT.SINGLE | SWT.BORDER); |
| final GridData gd= new GridData(SWT.LEFT, SWT.CENTER, false, false); |
| gd.widthHint= LayoutUtil.hintWidth(textControl, 2); |
| textControl.setLayoutData(gd); |
| final Label typeControl= new Label(composite, SWT.LEFT); |
| typeControl.setText(this.stdIndentSettings.getLevelUnitLabel()); |
| typeControl.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); |
| return textControl; |
| } |
| |
| private Control createMoreControls(final Composite parent) { |
| final Composite composite= new Composite(parent, SWT.NONE); |
| composite.setLayout(LayoutUtil.createTabGrid(2)); |
| |
| this.wsArgAssignBefore= new Button(composite, SWT.CHECK); |
| this.wsArgAssignBefore.setText(Messages.RCodeStyle_Whitespace_ArgAssign_Before_message); |
| this.wsArgAssignBefore.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); |
| |
| this.wsArgAssignBehind= new Button(composite, SWT.CHECK); |
| this.wsArgAssignBehind.setText(Messages.RCodeStyle_Whitespace_ArgAssign_Behind_message); |
| this.wsArgAssignBehind.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); |
| |
| LayoutUtil.addSmallFiller(composite, false); |
| |
| this.nlFDefBodyBlockBefore= new Button(composite, SWT.CHECK); |
| this.nlFDefBodyBlockBefore.setText(Messages.RCodeStyle_Newline_FDefBodyBlock_Before_message); |
| this.nlFDefBodyBlockBefore.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); |
| |
| return composite; |
| } |
| |
| @Override |
| protected void addBindings(final DataBindingSupport db) { |
| this.stdIndentSettings.addBindings(db, this.model); |
| |
| db.getContext().bindValue( |
| WidgetProperties.text(SWT.Modify).observe(this.indentBlockDepth), |
| BeanProperties.value(RCodeStyleSettings.class, RCodeStyleSettings.INDENT_BLOCK_DEPTH_PROP) |
| .observe(db.getRealm(), this.model), |
| new UpdateValueStrategy().setAfterGetValidator(new IntegerValidator(1, 10, |
| Messages.RCodeStyle_Indent_IndentInBlocks_error_message )), |
| null ); |
| db.getContext().bindValue( |
| WidgetProperties.text(SWT.Modify).observe(this.indentGroupDepth), |
| BeanProperties.value(RCodeStyleSettings.class, RCodeStyleSettings.INDENT_GROUP_DEPTH_PROP) |
| .observe(db.getRealm(), this.model), |
| new UpdateValueStrategy().setAfterGetValidator(new IntegerValidator(1, 10, Messages.RCodeStyle_Indent_IndentInGroups_error_message)), |
| null ); |
| db.getContext().bindValue( |
| WidgetProperties.text(SWT.Modify).observe(this.indentWrappedCommandDepth), |
| BeanProperties.value(RCodeStyleSettings.class, RCodeStyleSettings.INDENT_WRAPPED_COMMAND_DEPTH_PROP) |
| .observe(db.getRealm(), this.model), |
| new UpdateValueStrategy().setAfterGetValidator(new IntegerValidator(1, 10, Messages.RCodeStyle_Indent_IndentOfWrappedCommands_error_message)), |
| null ); |
| |
| db.getContext().bindValue( |
| WidgetProperties.selection().observe(this.wsArgAssignBefore), |
| BeanProperties.value(RCodeStyleSettings.class, RCodeStyleSettings.WS_ARGASSIGN_BEFORE_PROP) |
| .observe(db.getRealm(), this.model) ); |
| db.getContext().bindValue( |
| WidgetProperties.selection().observe(this.wsArgAssignBehind), |
| BeanProperties.value(RCodeStyleSettings.class, RCodeStyleSettings.WS_ARGASSIGN_BEHIND_PROP) |
| .observe(db.getRealm(), this.model) ); |
| db.getContext().bindValue( |
| WidgetProperties.selection().observe(this.nlFDefBodyBlockBefore), |
| BeanProperties.value(RCodeStyleSettings.class, RCodeStyleSettings.NL_FDEF_BODYBLOCK_BEFOREP_PROP) |
| .observe(db.getRealm(), this.model) ); |
| } |
| |
| @Override |
| protected void updateControls() { |
| this.model.load(this); |
| this.model.resetDirty(); |
| getDataBinding().getContext().updateTargets(); // required for invalid target values |
| } |
| |
| @Override |
| protected void updatePreferences() { |
| if (this.model.isDirty()) { |
| this.model.resetDirty(); |
| setPrefValues(this.model.toPreferencesMap()); |
| } |
| } |
| |
| } |