de.walware.statet.r.internal.console.ui.launching.RConsoleOptionsTab.java Source code

Java tutorial

Introduction

Here is the source code for de.walware.statet.r.internal.console.ui.launching.RConsoleOptionsTab.java

Source

/*=============================================================================#
 # Copyright (c) 2008-2015 Stephan Wahlbrink (WalWare.de) and others.
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
 # http://www.eclipse.org/legal/epl-v10.html
 # 
 # Contributors:
 #     Stephan Wahlbrink - initial API and implementation
 #=============================================================================*/

package de.walware.statet.r.internal.console.ui.launching;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.databinding.DataBindingContext;
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.databinding.observable.set.WritableSet;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
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.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import de.walware.ecommons.databinding.IntegerValidator;
import de.walware.ecommons.databinding.jface.SWTMultiEnabledObservable;
import de.walware.ecommons.debug.ui.LaunchConfigTabWithDbc;
import de.walware.ecommons.ltk.ui.sourceediting.SnippetEditor;
import de.walware.ecommons.ltk.ui.sourceediting.SnippetEditorObservable;
import de.walware.ecommons.templates.TemplateVariableProcessor;
import de.walware.ecommons.ui.components.ButtonGroup;
import de.walware.ecommons.ui.components.DataAdapter;
import de.walware.ecommons.ui.util.LayoutUtil;
import de.walware.ecommons.ui.util.ViewerUtil;

import de.walware.statet.nico.core.util.HistoryTrackingConfiguration;
import de.walware.statet.nico.core.util.TrackingConfiguration;
import de.walware.statet.nico.core.util.TrackingConfiguration2LaunchConfiguration;
import de.walware.statet.nico.ui.util.TrackingConfigurationComposite;
import de.walware.statet.nico.ui.util.TrackingConfigurationDialog;

import de.walware.statet.r.console.ui.launching.RConsoleLaunching;
import de.walware.statet.r.internal.console.ui.RConsoleMessages;
import de.walware.statet.r.ui.sourceediting.RSourceViewerConfigurator;
import de.walware.statet.r.ui.sourceediting.RTemplateSourceViewerConfigurator;

/**
 * Launch config tab for common R console options
 * <ul>
 *   <li>History (not yet implemented)</li>
 *   <li>Option to pin console page</li>
 *   <li>Option for a startup snippet</li>
 * </ul>
 */
public class RConsoleOptionsTab extends LaunchConfigTabWithDbc {

    static final String TRANSCRIPT_TRACKING_ID = "transcript"; //$NON-NLS-1$
    static final String CUSTOM_TRACKING_ID_PREFIX = "custom"; //$NON-NLS-1$

    static final String TRACKING_IDS = "tracking.ids"; //$NON-NLS-1$
    static final String TRACKING_ENABLED_IDS = "tracking.enabled.ids"; //$NON-NLS-1$

    static final TrackingConfiguration2LaunchConfiguration TRACKING_UTIL = new TrackingConfiguration2LaunchConfiguration();

    static final String ATTR_INTEGRATION_ROOT = "de.walware.statet.r.debug/integration"; //$NON-NLS-1$
    static final String ATTR_INTEGRATION_RHELP_ENABLED = ATTR_INTEGRATION_ROOT + "integration.rhelp.enabled"; //$NON-NLS-1$
    static final String ATTR_INTEGRATION_RGRAPHICS_ASDEFAULT = ATTR_INTEGRATION_ROOT
            + "integration.rgraphics.asdefault"; //$NON-NLS-1$
    static final String ATTR_INTEGRATION_RDBGEXT_ENABLED = ATTR_INTEGRATION_ROOT + "integration.rdbgext.enabled"; //$NON-NLS-1$

    private Button fPinControl;
    private WritableValue fPinValue;

    private CheckboxTableViewer fTrackingTable;
    private ButtonGroup<TrackingConfiguration> fTrackingButtons;
    private WritableList fTrackingList;
    private WritableSet fTrackingEnabledSet;
    private int fTrackingMaxCustomId;

    private SnippetEditor fStartupSnippetEditor;
    private WritableValue fStartupSnippetValue;

    private Button fRHelpByStatetControl;
    private WritableValue fRHelpByStatetValue;
    private Button fRGraphicsByStatetControl;
    private WritableValue fRGraphicsByStatetValue;
    private Button fRDbgExtControl;
    private WritableValue fRDbgExtValue;

    private Button fObjectDBEnabledControl;
    private WritableValue fObjectDBEnabledValue;
    private Button fObjectDBAutoEnabledControl;
    private WritableValue fObjectDBAutoEnabledValue;
    private Text fObjectDBListsChildrenControl;
    private WritableValue fObjectDBListsChildrenValue;
    private Text fObjectDBEnvsChildrenControl;
    private WritableValue fObjectDBEnvsChildrenValue;

    public RConsoleOptionsTab() {
    }

    @Override
    public String getName() {
        return RConsoleMessages.RConsole_OptionsTab_name;
    }

    @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(GridLayoutFactory.swtDefaults().create());

        final Composite consoleComposite = createConsoleOptions(mainComposite);
        if (consoleComposite != null) {
            consoleComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        }
        final Composite trackingComposite = createTrackingOptions(mainComposite);
        if (trackingComposite != null) {
            trackingComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        }

        { // Snippet options:
            final Group group = new Group(mainComposite, SWT.NONE);
            group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 4));
            group.setText("R snippet run after startup:");
            createSnippetOptions(group);
        }

        { // Object DB options:
            final Group group = new Group(mainComposite, SWT.NONE);
            group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
            group.setText("Eclipse Integration:");
            createEclipseOptions(group);
        }

        Dialog.applyDialogFont(parent);

        initBindings();
        fTrackingButtons.updateState();
    }

    private Composite createConsoleOptions(final Composite parent) {
        final Group group = new Group(parent, SWT.NONE);
        group.setText(RConsoleMessages.RConsole_MainTab_ConsoleOptions_label);
        group.setLayout(LayoutUtil.createGroupGrid(2));

        fPinControl = new Button(group, SWT.CHECK);
        fPinControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
        fPinControl.setText(RConsoleMessages.RConsole_MainTab_ConsoleOptions_Pin_label);

        return group;
    }

    private Composite createTrackingOptions(final Composite parent) {
        final Group group = new Group(parent, SWT.NONE);
        group.setText("History / Transcript / Tracking:");
        group.setLayout(LayoutUtil.createGroupGrid(2));

        final ViewerUtil.CheckboxTableComposite trackingTable;
        {
            trackingTable = new ViewerUtil.CheckboxTableComposite(group,
                    SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
            final GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
            gd.heightHint = LayoutUtil.hintHeight(trackingTable.table, 5);
            trackingTable.setLayoutData(gd);
            fTrackingTable = trackingTable.viewer;
        }
        {
            final TableViewerColumn column = trackingTable.addColumn("Name", SWT.LEFT, new ColumnWeightData(100));
            column.setLabelProvider(new CellLabelProvider() {
                @Override
                public void update(final ViewerCell cell) {
                    final TrackingConfiguration config = (TrackingConfiguration) cell.getElement();
                    cell.setText(config.getName());
                }
            });
        }

        fTrackingButtons = new ButtonGroup<TrackingConfiguration>(group) {
            @Override
            protected TrackingConfiguration edit1(TrackingConfiguration item, final boolean newItem,
                    final Object parent) {
                TrackingConfigurationDialog dialog;
                if (!newItem && item != null
                        && item.getId().equals(HistoryTrackingConfiguration.HISTORY_TRACKING_ID)) {
                    item = new HistoryTrackingConfiguration(item.getId(), (HistoryTrackingConfiguration) item);
                    dialog = new TrackingConfigurationDialog(RConsoleOptionsTab.this.getShell(), item, false) {
                        @Override
                        protected TrackingConfigurationComposite createConfigComposite(final Composite parent) {
                            return new RHistoryConfigurationComposite(parent);
                        }
                    };
                } else {
                    if (newItem) {
                        final String id = CUSTOM_TRACKING_ID_PREFIX + (fTrackingMaxCustomId + 1);
                        if (item == null) {
                            item = new TrackingConfiguration(id);
                        } else {
                            item = new TrackingConfiguration(id, item);
                        }
                    } else {
                        item = new TrackingConfiguration(item.getId(), item);
                    }
                    dialog = new TrackingConfigurationDialog(RConsoleOptionsTab.this.getShell(), item, newItem) {
                        @Override
                        protected TrackingConfigurationComposite createConfigComposite(final Composite parent) {
                            return new RTrackingConfigurationComposite(parent);
                        }
                    };
                }
                if (dialog.open() == Dialog.OK) {
                    if (newItem) {
                        fTrackingMaxCustomId++;
                    }
                    return item;
                }
                return null;
            }
        };
        fTrackingButtons.addAddButton(null);
        fTrackingButtons.addDeleteButton(null);
        fTrackingButtons.addEditButton(null);
        fTrackingButtons.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));

        ViewerUtil.scheduleStandardSelection(fTrackingTable);

        return group;
    }

    private void createSnippetOptions(final Composite container) {
        container.setLayout(LayoutUtil.createGroupGrid(1));

        final TemplateVariableProcessor templateVariableProcessor = new TemplateVariableProcessor();
        final RSourceViewerConfigurator configurator = new RTemplateSourceViewerConfigurator(null,
                templateVariableProcessor);
        fStartupSnippetEditor = new SnippetEditor(configurator);
        fStartupSnippetEditor.create(container, SnippetEditor.DEFAULT_MULTI_LINE_STYLE);
        final GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        gd.heightHint = LayoutUtil.hintHeight(fStartupSnippetEditor.getSourceViewer().getTextWidget(), 8);
        fStartupSnippetEditor.getControl().setLayoutData(gd);
    }

    private void createEclipseOptions(final Composite container) {
        container.setLayout(LayoutUtil.createGroupGrid(2));

        {
            fRHelpByStatetControl = new Button(container, SWT.CHECK);
            final GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
            fRHelpByStatetControl.setLayoutData(gd);
            fRHelpByStatetControl
                    .setText("Enable R Help by StatET for help functions in R ('help', 'help.start', '?')");
        }
        {
            fRGraphicsByStatetControl = new Button(container, SWT.CHECK);
            final GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
            fRGraphicsByStatetControl.setLayoutData(gd);
            fRGraphicsByStatetControl
                    .setText("Set R Graphic view by StatET as default graphic device for new plots in R");
        }
        {
            fRDbgExtControl = new Button(container, SWT.CHECK);
            final GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
            fRDbgExtControl.setLayoutData(gd);
            fRDbgExtControl.setText("Enable extensions by StatET for improved debug support of R code");
        }

        {
            fObjectDBEnabledControl = new Button(container, SWT.CHECK);
            fObjectDBEnabledControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
            fObjectDBEnabledControl.setText("Enable Object DB (for Object Browser etc.)");
        }

        {
            fObjectDBAutoEnabledControl = new Button(container, SWT.CHECK);
            final GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
            gd.horizontalIndent = LayoutUtil.defaultIndent();
            fObjectDBAutoEnabledControl.setLayoutData(gd);
            fObjectDBAutoEnabledControl.setText("Refresh DB automatically (initial setting)");
        }
        {
            final Label label = new Label(container, SWT.NONE);
            label.setText("Max length of R lists to fetch:");
            final GridData gd = new GridData(SWT.FILL, SWT.FILL, false, false);
            gd.horizontalIndent = LayoutUtil.defaultIndent();
            label.setLayoutData(gd);
        }
        {
            fObjectDBListsChildrenControl = new Text(container, SWT.BORDER);
            fObjectDBListsChildrenControl.setTextLimit(10);
            final GridData gd = new GridData(SWT.LEFT, SWT.FILL, true, false);
            gd.widthHint = LayoutUtil.hintWidth(fObjectDBListsChildrenControl, 10);
            fObjectDBListsChildrenControl.setLayoutData(gd);
        }
        {
            final Label label = new Label(container, SWT.NONE);
            label.setText("Max length of R environments to fetch:");
            final GridData gd = new GridData(SWT.FILL, SWT.FILL, false, false);
            gd.horizontalIndent = LayoutUtil.defaultIndent();
            label.setLayoutData(gd);
        }
        {
            fObjectDBEnvsChildrenControl = new Text(container, SWT.BORDER);
            fObjectDBEnvsChildrenControl.setTextLimit(10);
            final GridData gd = new GridData(SWT.LEFT, SWT.FILL, true, false);
            gd.widthHint = LayoutUtil.hintWidth(fObjectDBEnvsChildrenControl, 10);
            fObjectDBEnvsChildrenControl.setLayoutData(gd);
        }
    }

    @Override
    protected void addBindings(final DataBindingContext dbc, final Realm realm) {
        fPinValue = new WritableValue(realm, Boolean.class);
        dbc.bindValue(SWTObservables.observeSelection(fPinControl), fPinValue, null, null);

        fTrackingList = new WritableList(realm, new ArrayList<Object>(), TrackingConfiguration.class);
        fTrackingTable.setContentProvider(new ObservableListContentProvider());
        fTrackingTable.setInput(fTrackingList);

        fStartupSnippetValue = new WritableValue(realm, String.class);
        dbc.bindValue(new SnippetEditorObservable(realm, fStartupSnippetEditor, SWT.Modify), fStartupSnippetValue,
                null, null);

        fRHelpByStatetValue = new WritableValue(realm, Boolean.class);
        fRGraphicsByStatetValue = new WritableValue(realm, Boolean.class);
        fRDbgExtValue = new WritableValue(realm, Boolean.class);
        dbc.bindValue(SWTObservables.observeSelection(fRHelpByStatetControl), fRHelpByStatetValue, null, null);
        dbc.bindValue(SWTObservables.observeSelection(fRGraphicsByStatetControl), fRGraphicsByStatetValue, null,
                null);
        dbc.bindValue(SWTObservables.observeSelection(fRDbgExtControl), fRDbgExtValue, null, null);

        fObjectDBEnabledValue = new WritableValue(realm, Boolean.class);
        fObjectDBAutoEnabledValue = new WritableValue(realm, Boolean.class);
        fObjectDBListsChildrenValue = new WritableValue(realm, Integer.class);
        fObjectDBEnvsChildrenValue = new WritableValue(realm, Integer.class);
        final ISWTObservableValue dbObs = SWTObservables.observeSelection(fObjectDBEnabledControl);
        dbc.bindValue(dbObs, fObjectDBEnabledValue, null, null);
        dbc.bindValue(SWTObservables.observeSelection(fObjectDBAutoEnabledControl), fObjectDBAutoEnabledValue, null,
                null);
        dbc.bindValue(SWTObservables.observeText(fObjectDBListsChildrenControl, SWT.Modify),
                fObjectDBListsChildrenValue,
                new UpdateValueStrategy().setAfterGetValidator(new IntegerValidator(100, Integer.MAX_VALUE,
                        "Invalid max value for length of R lists to fetch (100-).")),
                null);
        dbc.bindValue(SWTObservables.observeText(fObjectDBEnvsChildrenControl, SWT.Modify),
                fObjectDBEnvsChildrenValue, new UpdateValueStrategy().setAfterGetValidator(new IntegerValidator(100,
                        Integer.MAX_VALUE, "Invalid max value for length of R environments to fetch (100-).")),
                null);

        dbc.bindValue(new SWTMultiEnabledObservable(realm, new Control[] { fObjectDBAutoEnabledControl,
                fObjectDBEnvsChildrenControl, fObjectDBListsChildrenControl, }, null), dbObs, null, null);

        fTrackingButtons.connectTo(fTrackingTable,
                new DataAdapter.ListAdapter<TrackingConfiguration>(fTrackingList, null) {
                    @Override
                    public boolean isDeleteAllowed(final Object element) {
                        return (super.isDeleteAllowed(element)
                                && ((TrackingConfiguration) element).getId().startsWith(CUSTOM_TRACKING_ID_PREFIX));
                    }
                });

        fTrackingEnabledSet = new WritableSet(realm, new HashSet<Object>(), TrackingConfiguration.class);
        fTrackingButtons.setCheckedModel(fTrackingEnabledSet);
        dbc.bindSet(ViewersObservables.observeCheckedElements(fTrackingTable, TrackingConfiguration.class),
                fTrackingEnabledSet);
    }

    @Override
    public void setDefaults(final ILaunchConfigurationWorkingCopy configuration) {
    }

    @Override
    protected void doInitialize(final ILaunchConfiguration configuration) {
        boolean pin;
        try {
            pin = configuration.getAttribute(RConsoleLaunching.ATTR_PIN_CONSOLE, false);
        } catch (final CoreException e) {
            pin = false;
            logReadingError(e);
        }
        fPinValue.setValue(pin);

        {
            boolean enabled = true;
            try {
                enabled = configuration.getAttribute(ATTR_INTEGRATION_RHELP_ENABLED, enabled);
            } catch (final CoreException e) {
                logReadingError(e);
            }
            fRHelpByStatetValue.setValue(enabled);
        }
        {
            boolean enabled = true;
            try {
                enabled = configuration.getAttribute(ATTR_INTEGRATION_RGRAPHICS_ASDEFAULT, enabled);
            } catch (final CoreException e) {
                logReadingError(e);
            }
            fRGraphicsByStatetValue.setValue(enabled);
        }
        {
            boolean enabled = true;
            try {
                enabled = configuration.getAttribute(ATTR_INTEGRATION_RDBGEXT_ENABLED, enabled);
            } catch (final CoreException e) {
                logReadingError(e);
            }
            fRDbgExtValue.setValue(enabled);
        }

        String startupSnippet;
        try {
            startupSnippet = configuration.getAttribute(RConsoleLaunching.ATTR_INIT_SCRIPT_SNIPPET, ""); //$NON-NLS-1$
        } catch (final CoreException e) {
            startupSnippet = ""; //$NON-NLS-1$
            logReadingError(e);
        }
        fStartupSnippetValue.setValue(startupSnippet);

        {
            boolean enabled = true;
            try {
                enabled = configuration.getAttribute(RConsoleLaunching.ATTR_OBJECTDB_ENABLED, enabled);
            } catch (final CoreException e) {
                logReadingError(e);
            }
            fObjectDBEnabledValue.setValue(enabled);
        }
        {
            boolean enabled = true;
            try {
                enabled = configuration.getAttribute(RConsoleLaunching.ATTR_OBJECTDB_AUTOREFRESH_ENABLED, enabled);
            } catch (final CoreException e) {
                logReadingError(e);
            }
            fObjectDBAutoEnabledValue.setValue(enabled);
        }
        {
            int max = 200000;
            try {
                max = configuration.getAttribute(RConsoleLaunching.ATTR_OBJECTDB_LISTS_MAX_LENGTH, max);
            } catch (final CoreException e) {
                logReadingError(e);
            }
            fObjectDBListsChildrenValue.setValue(max);
        }
        {
            int max = 20000;
            try {
                max = configuration.getAttribute(RConsoleLaunching.ATTR_OBJECTDB_ENVS_MAX_LENGTH, max);
            } catch (final CoreException e) {
                logReadingError(e);
            }
            fObjectDBEnvsChildrenValue.setValue(max);
        }

        {
            fTrackingList.clear();
            fTrackingMaxCustomId = 0;
            List<String> trackingIds = Collections.EMPTY_LIST;
            try {
                trackingIds = configuration.getAttribute(TRACKING_IDS, Collections.EMPTY_LIST);
                for (final String id : trackingIds) {
                    final TrackingConfiguration trackingConfig = id.equals(
                            HistoryTrackingConfiguration.HISTORY_TRACKING_ID) ? new HistoryTrackingConfiguration(id)
                                    : new TrackingConfiguration(id);
                    try {
                        TRACKING_UTIL.load(trackingConfig, configuration);
                        fTrackingList.add(trackingConfig);
                        if (id.startsWith(CUSTOM_TRACKING_ID_PREFIX)) {
                            try {
                                final int num = Integer.parseInt(id.substring(CUSTOM_TRACKING_ID_PREFIX.length()));
                                fTrackingMaxCustomId = Math.max(fTrackingMaxCustomId, num);
                            } catch (final Exception e) {
                            }
                        }
                    } catch (final CoreException e) {
                        trackingIds.remove(id);
                        logReadingError(e);
                    }
                }
            } catch (final CoreException e) {
                logReadingError(e);
            }
            if (!trackingIds.contains(HistoryTrackingConfiguration.HISTORY_TRACKING_ID)) {
                final TrackingConfiguration trackingConfig = new HistoryTrackingConfiguration(
                        HistoryTrackingConfiguration.HISTORY_TRACKING_ID);
                trackingConfig.setName("History");
                trackingConfig.setFilePath(RHistoryConfigurationComposite.HISTORY_TRACKING_DEFAULT_PATH);
                fTrackingList.add(trackingConfig);
            }
            if (!trackingIds.contains(TRANSCRIPT_TRACKING_ID)) {
                final TrackingConfiguration trackingConfig = new TrackingConfiguration(TRANSCRIPT_TRACKING_ID);
                trackingConfig.setName("Transcript");
                trackingConfig.setFilePath(RTrackingConfigurationComposite.TRANSCRIPT_TRACKING_DEFAULT_PATH);
                fTrackingList.add(trackingConfig);
            }
        }

        {
            fTrackingEnabledSet.clear();
            List<String> trackingEnabledIds = Collections.emptyList();
            try {
                trackingEnabledIds = configuration.getAttribute(TRACKING_ENABLED_IDS, Collections.EMPTY_LIST);
                final List<TrackingConfiguration> trackingList = fTrackingList;
                for (final TrackingConfiguration trackingConfig : trackingList) {
                    if (trackingEnabledIds.contains(trackingConfig.getId())) {
                        fTrackingEnabledSet.add(trackingConfig);
                    }
                }
            } catch (final CoreException e) {
                logReadingError(e);
            }
        }
    }

    @Override
    protected void doSave(final ILaunchConfigurationWorkingCopy configuration) {
        configuration.setAttribute(RConsoleLaunching.ATTR_PIN_CONSOLE,
                ((Boolean) fPinValue.getValue()).booleanValue());

        {
            final Boolean enabled = (Boolean) fRHelpByStatetValue.getValue();
            configuration.setAttribute(ATTR_INTEGRATION_RHELP_ENABLED, enabled.booleanValue());
        }
        {
            final Boolean enabled = (Boolean) fRGraphicsByStatetValue.getValue();
            configuration.setAttribute(ATTR_INTEGRATION_RGRAPHICS_ASDEFAULT, enabled.booleanValue());
        }
        {
            final Boolean enabled = (Boolean) fRDbgExtValue.getValue();
            configuration.setAttribute(ATTR_INTEGRATION_RDBGEXT_ENABLED, enabled.booleanValue());
        }

        final String startupSnippet = (String) fStartupSnippetValue.getValue();
        if (startupSnippet != null && startupSnippet.length() > 0) {
            configuration.setAttribute(RConsoleLaunching.ATTR_INIT_SCRIPT_SNIPPET, startupSnippet);
        } else {
            configuration.removeAttribute(RConsoleLaunching.ATTR_INIT_SCRIPT_SNIPPET);
        }

        {
            final Boolean enabled = (Boolean) fObjectDBEnabledValue.getValue();
            configuration.setAttribute(RConsoleLaunching.ATTR_OBJECTDB_ENABLED, enabled.booleanValue());
        }
        {
            final Boolean enabled = (Boolean) fObjectDBAutoEnabledValue.getValue();
            configuration.setAttribute(RConsoleLaunching.ATTR_OBJECTDB_AUTOREFRESH_ENABLED, enabled.booleanValue());
        }
        {
            final Integer max = (Integer) fObjectDBListsChildrenValue.getValue();
            configuration.setAttribute(RConsoleLaunching.ATTR_OBJECTDB_LISTS_MAX_LENGTH, max.intValue());
        }
        {
            final Integer max = (Integer) fObjectDBEnvsChildrenValue.getValue();
            configuration.setAttribute(RConsoleLaunching.ATTR_OBJECTDB_ENVS_MAX_LENGTH, max.intValue());
        }

        final List<String> trackingIds = new ArrayList<String>(fTrackingList.size());

        final List<TrackingConfiguration> trackingList = fTrackingList;
        for (final TrackingConfiguration trackingConfig : trackingList) {
            final String id = trackingConfig.getId();
            trackingIds.add(id);
            TRACKING_UTIL.save(trackingConfig, configuration);
        }
        configuration.setAttribute(TRACKING_IDS, trackingIds);

        final List<String> trackingEnabledIds = new ArrayList<String>(fTrackingEnabledSet.size());
        final Set<TrackingConfiguration> trackingEnabledSet = fTrackingEnabledSet;
        for (final TrackingConfiguration trackingConfig : trackingEnabledSet) {
            final String id = trackingConfig.getId();
            trackingEnabledIds.add(id);
        }
        configuration.setAttribute(TRACKING_ENABLED_IDS, trackingEnabledIds);
    }

}