blob: 57e2bdb9567a9350f5a7f13602a2e570117977ba [file] [log] [blame]
/*=============================================================================#
# 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());
}
}
}