/*******************************************************************************
* Copyright (c) 2009 Andrey Loskutov.
* 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
* Contributor: Andrey Loskutov - initial API and implementation
*******************************************************************************/
package de.loskutov.anyedit.ui.preferences;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
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.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.dialogs.PropertyPage;
import org.osgi.service.prefs.BackingStoreException;
import de.loskutov.anyedit.AnyEditToolsPlugin;
import de.loskutov.anyedit.IAnyEditConstants;
import de.loskutov.anyedit.Messages;
import de.loskutov.anyedit.actions.AbstractTextAction;
import de.loskutov.anyedit.util.EclipseUtils;
public class ProjectPreferencePage extends PropertyPage {
private TabFolder tabFolder;
private Group saveComposite;
private Button enableProjectCheck;
private Button saveAndTrimCheck;
private Button ignoreBlankLinesCheck;
private Button saveAndAddLineCheck;
private Button saveAndFixLineDelimitersCheck;
private Button saveAndConvertCheck;
private Button useModulo4TabsCheck;
private Group convertChoiceComposite;
private Button convertTabsOnSaveRadio;
private Button convertSpacesOnSaveRadio;
private Label fTableLabel;
private Table fFilterTable;
private CheckboxTableViewer fFilterViewer;
private TableEditor fTableEditor;
private FilterContentProvider fStepFilterContentProvider;
private Button fRemoveFilterButton;
private Button fAddFilterButton;
private Button fEnableAllButton;
private Button fDisableAllButton;
private TableItem fNewTableItem;
private Filter fNewStepFilter;
private Text fEditorText;
private Text tabWidthText;
private Button useJavaTabsCheck;
private Button removeTrailingSpacesCheck;
private Button fixLineDelimitersCheck;
private Button replaceAllTabsCheck;
private Button replaceAllSpacesCheck;
private IEclipsePreferences prefs;
private String fInvalidEditorText;
private Button addNewLineCheck;
private Group exclGroup;
public ProjectPreferencePage() {
super();
}
private void initPreferences() {
IScopeContext projectScope = new ProjectScope((IProject) getElement());
prefs = projectScope.getNode(AnyEditToolsPlugin.getDefault().getBundle()
.getSymbolicName());
}
@Override
protected Control createContents(Composite parent) {
initPreferences();
createWorkspaceButtons(parent);
tabFolder = new TabFolder(parent, SWT.TOP);
createTabAutoSave();
createTabConvert();
setProjectEnabled(enableProjectCheck.getSelection());
return tabFolder;
}
private void createWorkspaceButtons(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setFont(parent.getFont());
GridLayout layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.numColumns = 2;
composite.setLayout(layout);
composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
boolean projectPropsEnabled = prefs.getBoolean(
IAnyEditConstants.PROJECT_PROPS_ENABLED, false);
enableProjectCheck = AnyEditPreferencePage.createLabeledCheck(
"Enable project specific settings",
"These settings would be used for all files from the current project",
projectPropsEnabled, composite);
enableProjectCheck.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
setProjectEnabled(enableProjectCheck.getSelection());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// ignored
}
});
Link workspaceSettingsLink = createLink(composite, "Configure Workspace Settings...");
workspaceSettingsLink
.setLayoutData(new GridData(SWT.END, SWT.CENTER, true, false));
}
private Link createLink(Composite composite, String text) {
Link link = new Link(composite, SWT.NONE);
link.setFont(composite.getFont());
link.setText("<A>" + text + "</A>");
link.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
String id = "AnyEditPreferencePage";
PreferencesUtil.createPreferenceDialogOn(getShell(), id,
new String[] { id }, null).open();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
String id = "AnyEditPreferencePage";
PreferencesUtil.createPreferenceDialogOn(getShell(), id,
new String[] { id }, null).open();
}
});
return link;
}
@Override
public boolean performOk() {
prefs.putBoolean(IAnyEditConstants.PROJECT_PROPS_ENABLED, enableProjectCheck.getSelection());
fStepFilterContentProvider.saveFilters();
prefs.put(IAnyEditConstants.EDITOR_TAB_WIDTH, tabWidthText.getText());
prefs.putBoolean(IAnyEditConstants.USE_JAVA_TAB_WIDTH_FOR_JAVA, useJavaTabsCheck
.getSelection());
prefs.putBoolean(IAnyEditConstants.USE_MODULO_CALCULATION_FOR_TABS_REPLACE,
useModulo4TabsCheck.getSelection());
prefs.putBoolean(IAnyEditConstants.REMOVE_TRAILING_SPACES,
removeTrailingSpacesCheck.getSelection());
prefs.putBoolean(IAnyEditConstants.FIX_LINE_DELIMITERS,
fixLineDelimitersCheck.getSelection());
prefs.putBoolean(IAnyEditConstants.ADD_NEW_LINE,
addNewLineCheck.getSelection());
prefs.putBoolean(IAnyEditConstants.REPLACE_ALL_TABS_WITH_SPACES,
replaceAllTabsCheck.getSelection());
prefs.putBoolean(IAnyEditConstants.REPLACE_ALL_SPACES_WITH_TABS,
replaceAllSpacesCheck.getSelection());
prefs.putBoolean(IAnyEditConstants.SAVE_AND_TRIM_ENABLED, saveAndTrimCheck
.getSelection());
prefs.putBoolean(IAnyEditConstants.IGNORE_BLANK_LINES_WHEN_TRIMMING, ignoreBlankLinesCheck
.getSelection());
prefs.putBoolean(IAnyEditConstants.SAVE_AND_ADD_LINE, saveAndAddLineCheck
.getSelection());
prefs.putBoolean(IAnyEditConstants.SAVE_AND_FIX_LINE_DELIMITERS, saveAndFixLineDelimitersCheck
.getSelection());
prefs.putBoolean(IAnyEditConstants.SAVE_AND_CONVERT_ENABLED, saveAndConvertCheck
.getSelection());
if (convertSpacesOnSaveRadio.getSelection()) {
prefs.put(IAnyEditConstants.CONVERT_ACTION_ON_SAVE,
AbstractTextAction.ACTION_ID_CONVERT_SPACES);
} else {
prefs.put(IAnyEditConstants.CONVERT_ACTION_ON_SAVE,
AbstractTextAction.ACTION_ID_CONVERT_TABS);
}
try {
prefs.flush();
} catch (BackingStoreException e) {
AnyEditToolsPlugin.errorDialog("Couldn't save project preferences", e);
}
return true;
}
@Override
protected void performDefaults() {
if (!enableProjectCheck.getSelection()) {
return;
}
super.performDefaults();
IPreferenceStore defaultStore = AnyEditToolsPlugin.getDefault()
.getPreferenceStore();
tabWidthText.setText(defaultStore
.getDefaultString(IAnyEditConstants.EDITOR_TAB_WIDTH));
useJavaTabsCheck.setSelection(defaultStore
.getDefaultBoolean(IAnyEditConstants.USE_JAVA_TAB_WIDTH_FOR_JAVA));
useModulo4TabsCheck.setSelection(defaultStore
.getDefaultBoolean(IAnyEditConstants.USE_MODULO_CALCULATION_FOR_TABS_REPLACE));
removeTrailingSpacesCheck.setSelection(defaultStore
.getDefaultBoolean(IAnyEditConstants.REMOVE_TRAILING_SPACES));
fixLineDelimitersCheck.setSelection(defaultStore
.getDefaultBoolean(IAnyEditConstants.FIX_LINE_DELIMITERS));
addNewLineCheck.setSelection(defaultStore
.getDefaultBoolean(IAnyEditConstants.ADD_NEW_LINE));
replaceAllTabsCheck.setSelection(defaultStore
.getDefaultBoolean(IAnyEditConstants.REPLACE_ALL_TABS_WITH_SPACES));
replaceAllSpacesCheck.setSelection(defaultStore
.getDefaultBoolean(IAnyEditConstants.REPLACE_ALL_SPACES_WITH_TABS));
saveAndTrimCheck.setSelection(defaultStore
.getDefaultBoolean(IAnyEditConstants.SAVE_AND_TRIM_ENABLED));
saveAndAddLineCheck.setSelection(defaultStore
.getDefaultBoolean(IAnyEditConstants.SAVE_AND_ADD_LINE));
saveAndFixLineDelimitersCheck.setSelection(defaultStore
.getDefaultBoolean(IAnyEditConstants.SAVE_AND_FIX_LINE_DELIMITERS));
ignoreBlankLinesCheck.setSelection(defaultStore
.getDefaultBoolean(IAnyEditConstants.IGNORE_BLANK_LINES_WHEN_TRIMMING));
saveAndConvertCheck.setSelection(defaultStore
.getDefaultBoolean(IAnyEditConstants.SAVE_AND_CONVERT_ENABLED));
boolean convertTabsAction = AbstractTextAction.ACTION_ID_CONVERT_TABS
.equals(defaultStore
.getDefaultString(IAnyEditConstants.CONVERT_ACTION_ON_SAVE));
boolean isSaveHookEnabled = AnyEditToolsPlugin.isSaveHookInitialized();
convertTabsOnSaveRadio.setSelection(convertTabsAction);
convertSpacesOnSaveRadio.setSelection(!convertTabsAction);
fStepFilterContentProvider.setDefaults();
convertTabsOnSaveRadio.setEnabled(isSaveHookEnabled
&& saveAndConvertCheck.getSelection());
convertSpacesOnSaveRadio.setEnabled(isSaveHookEnabled
&& saveAndConvertCheck.getSelection());
convertChoiceComposite.setEnabled(isSaveHookEnabled
&& saveAndConvertCheck.getSelection());
}
/* @SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") */
private void createTabAutoSave() {
TabItem tabAuto = new TabItem(tabFolder, SWT.NONE);
tabAuto.setText(Messages.pref_tab_auto);
Composite defPanel = AnyEditPreferencePage.createContainer(tabFolder);
tabAuto.setControl(defPanel);
boolean isSaveHookEnabled = AnyEditToolsPlugin.isSaveHookInitialized();
saveComposite = new Group(defPanel, SWT.SHADOW_ETCHED_IN);
GridLayout layout = new GridLayout();
saveComposite.setLayout(layout);
GridData gridData = new GridData(GridData.FILL_HORIZONTAL
| GridData.GRAB_HORIZONTAL );
saveComposite.setLayoutData(gridData);
String saveGroupText = Messages.pref_saveIntro;
if (!isSaveHookEnabled) {
saveComposite.setToolTipText(saveGroupText);
Label label = new Label(saveComposite, SWT.WRAP);
Color red = tabFolder.getDisplay().getSystemColor(SWT.COLOR_RED);
label.setForeground(red);
label.setText(Messages.pref_saveHookNotEnabled);
}
saveComposite.setText(saveGroupText);
Composite firstRow = new Composite(saveComposite, SWT.NONE);
layout = new GridLayout(2, false);
firstRow.setLayout(layout);
gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL);
gridData.horizontalIndent = -5;
firstRow.setLayoutData(gridData);
IPreferenceStore defaultStore = AnyEditToolsPlugin.getDefault()
.getPreferenceStore();
saveAndTrimCheck = AnyEditPreferencePage.createLabeledCheck(
Messages.pref_saveAndTrim, Messages.pref_saveAndTrimTip, prefs
.getBoolean(IAnyEditConstants.SAVE_AND_TRIM_ENABLED, defaultStore
.getDefaultBoolean(IAnyEditConstants.SAVE_AND_TRIM_ENABLED)),
firstRow);
ignoreBlankLinesCheck = AnyEditPreferencePage.createLabeledCheck(
Messages.pref_ignoreOnTrim, Messages.pref_ignoreOnTrimTip, prefs
.getBoolean(IAnyEditConstants.IGNORE_BLANK_LINES_WHEN_TRIMMING, defaultStore
.getDefaultBoolean(IAnyEditConstants.IGNORE_BLANK_LINES_WHEN_TRIMMING)),
firstRow);
saveAndAddLineCheck = AnyEditPreferencePage.createLabeledCheck(
Messages.pref_saveAndAddLine, Messages.pref_saveAndAddLineTip, prefs
.getBoolean(IAnyEditConstants.SAVE_AND_ADD_LINE, defaultStore
.getDefaultBoolean(IAnyEditConstants.SAVE_AND_ADD_LINE)),
firstRow);
saveAndFixLineDelimitersCheck = AnyEditPreferencePage.createLabeledCheck(
Messages.pref_saveAndFixLineDelimiters, Messages.pref_saveAndFixLineDelimitersTip, prefs
.getBoolean(IAnyEditConstants.SAVE_AND_FIX_LINE_DELIMITERS, defaultStore
.getDefaultBoolean(IAnyEditConstants.SAVE_AND_FIX_LINE_DELIMITERS)),
firstRow);
saveAndConvertCheck = AnyEditPreferencePage.createLabeledCheck(
Messages.pref_saveAndConvert, Messages.pref_saveAndConvertTip,
prefs.getBoolean(IAnyEditConstants.SAVE_AND_CONVERT_ENABLED, defaultStore
.getDefaultBoolean(IAnyEditConstants.SAVE_AND_CONVERT_ENABLED)),
saveComposite);
convertChoiceComposite = new Group(saveComposite, SWT.SHADOW_ETCHED_IN);// SWT.SHADOW_NONE
layout = new GridLayout();
layout.numColumns = 2;
convertChoiceComposite.setLayout(layout);
gridData = new GridData(300, 50);
gridData.horizontalIndent = 20;
convertChoiceComposite.setLayoutData(gridData);
convertChoiceComposite.setText(Messages.pref_convertChoiceIntro);
boolean convertTabsAction = AbstractTextAction.ACTION_ID_CONVERT_TABS
.equals(prefs.get(IAnyEditConstants.CONVERT_ACTION_ON_SAVE, defaultStore
.getDefaultString(IAnyEditConstants.CONVERT_ACTION_ON_SAVE)));
convertTabsOnSaveRadio = AnyEditPreferencePage.createLabeledRadio(
Messages.pref_convertTabsOnSave, Messages.pref_convertTabsOnSaveTip,
convertTabsAction, convertChoiceComposite);
convertSpacesOnSaveRadio = AnyEditPreferencePage.createLabeledRadio(
Messages.pref_convertSpacesOnSave, Messages.pref_convertSpacesOnSaveTip,
!convertTabsAction, convertChoiceComposite);
saveAndConvertCheck.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
convertTabsOnSaveRadio.setEnabled(saveAndConvertCheck.getSelection());
convertSpacesOnSaveRadio.setEnabled(saveAndConvertCheck.getSelection());
convertChoiceComposite.setEnabled(saveAndConvertCheck.getSelection());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// ignored
}
});
convertTabsOnSaveRadio.setEnabled(isSaveHookEnabled
&& saveAndConvertCheck.getSelection());
convertSpacesOnSaveRadio.setEnabled(isSaveHookEnabled
&& saveAndConvertCheck.getSelection());
convertChoiceComposite.setEnabled(isSaveHookEnabled
&& saveAndConvertCheck.getSelection());
saveAndTrimCheck.setEnabled(isSaveHookEnabled);
ignoreBlankLinesCheck.setEnabled(isSaveHookEnabled);
saveAndAddLineCheck.setEnabled(isSaveHookEnabled);
saveAndFixLineDelimitersCheck.setEnabled(isSaveHookEnabled);
saveAndConvertCheck.setEnabled(isSaveHookEnabled);
saveComposite.setEnabled(isSaveHookEnabled);
createExclusionGroup(defPanel);
}
/**
* Enable/disable all UI elements except for project props enabled check
* @param selection
*/
/* @SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") */
protected void setProjectEnabled(boolean selection) {
tabFolder.setEnabled(selection);
saveComposite.setEnabled(selection);
saveAndTrimCheck.setEnabled(selection);
ignoreBlankLinesCheck.setEnabled(selection);
saveAndAddLineCheck.setEnabled(selection);
saveAndFixLineDelimitersCheck.setEnabled(selection);
saveAndConvertCheck.setEnabled(selection);
saveComposite.setEnabled(selection);
convertChoiceComposite.setEnabled(selection);
convertTabsOnSaveRadio.setEnabled(selection);
convertSpacesOnSaveRadio.setEnabled(selection);
fTableLabel.setEnabled(selection);
fFilterTable.setEnabled(selection);
tabWidthText.setEnabled(selection);
useJavaTabsCheck.setEnabled(selection);
useModulo4TabsCheck.setEnabled(selection);
removeTrailingSpacesCheck.setEnabled(selection);
fixLineDelimitersCheck.setEnabled(selection);
addNewLineCheck.setEnabled(selection);
replaceAllTabsCheck.setEnabled(selection);
replaceAllSpacesCheck.setEnabled(selection);
exclGroup.setEnabled(selection);
setFilterButtonsEnabled(selection);
}
private Control createExclusionGroup(Composite parent) {
// PreferenceLinkArea contentTypeArea = new PreferenceLinkArea(parent, SWT.NONE,
// "org.eclipse.ui.preferencePages.ContentTypes",
// getText("AnyEditPreferencePage.linkToContentTypes"),
// (IWorkbenchPreferenceContainer) getContainer(), null);
//
// GridData data = new GridData(GridData.FILL_HORIZONTAL |
// GridData.GRAB_HORIZONTAL);
// contentTypeArea.getControl().setLayoutData(data);
exclGroup = new Group(parent, SWT.SHADOW_ETCHED_IN);
exclGroup.setText(Messages.pref_group_exclude);
exclGroup.setToolTipText(Messages.pref_group_excludeTip);
GridLayout layout = new GridLayout();
exclGroup.setLayout(layout);
GridData gridData = new GridData(GridData.FILL_HORIZONTAL
| GridData.GRAB_HORIZONTAL);
exclGroup.setLayoutData(gridData);
createFilterPreferences(exclGroup);
return exclGroup;
}
/**
* Create a group to contain the step filter related widgetry
*/
private void createFilterPreferences(Composite parent) {
// top level container
Composite container = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginHeight = 0;
layout.marginWidth = 0;
container.setLayout(layout);
GridData gd = new GridData(GridData.FILL_HORIZONTAL
| GridData.VERTICAL_ALIGN_FILL);
container.setLayoutData(gd);
// table label
fTableLabel = new Label(container, SWT.WRAP);
fTableLabel.setText(Messages.pref_Defined_file_filters);
gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gd.horizontalSpan = 2;
fTableLabel.setLayoutData(gd);
fFilterTable = new Table(container, SWT.CHECK | SWT.H_SCROLL | SWT.V_SCROLL
| SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
fFilterTable.setHeaderVisible(false);
// fFilterTable.setLinesVisible(true);
fFilterTable.setLayoutData(new GridData(GridData.FILL_BOTH));
TableLayout tlayout = new TableLayout();
tlayout.addColumnData(new ColumnWeightData(100, true));
fFilterTable.setLayout(tlayout);
TableColumn tableCol = new TableColumn(fFilterTable, SWT.LEFT);
tableCol.setResizable(true);
fFilterViewer = new CheckboxTableViewer(fFilterTable);
fTableEditor = new TableEditor(fFilterTable);
fFilterViewer.setLabelProvider(new FilterLabelProvider());
fFilterViewer.setComparator(new FilterViewerSorter());
fStepFilterContentProvider = new FilterContentProvider(fFilterViewer);
fFilterViewer.setContentProvider(fStepFilterContentProvider);
// @todo table width input just needs to be non-null
fFilterViewer.setInput(this);
fFilterViewer.addCheckStateListener(new ICheckStateListener() {
@Override
public void checkStateChanged(CheckStateChangedEvent event) {
Filter filter = (Filter) event.getElement();
fStepFilterContentProvider.toggleFilter(filter);
}
});
fFilterViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
ISelection selection = event.getSelection();
if (selection.isEmpty()) {
fRemoveFilterButton.setEnabled(false);
} else {
fRemoveFilterButton.setEnabled(true);
}
}
});
createFilterButtons(container);
}
private void setFilterButtonsEnabled(boolean enabled) {
fAddFilterButton.setEnabled(enabled);
if (enabled) {
fRemoveFilterButton.setEnabled(!fFilterViewer.getSelection().isEmpty());
} else {
fRemoveFilterButton.setEnabled(enabled);
}
fEnableAllButton.setEnabled(enabled);
fDisableAllButton.setEnabled(enabled);
}
private void createFilterButtons(Composite container) {
// button container
Composite buttonContainer = new Composite(container, SWT.NONE);
GridData gd = new GridData(GridData.FILL_VERTICAL);
buttonContainer.setLayoutData(gd);
GridLayout buttonLayout = new GridLayout();
buttonLayout.numColumns = 1;
buttonLayout.marginHeight = 0;
buttonLayout.marginWidth = 0;
buttonContainer.setLayout(buttonLayout);
// Add filter button
fAddFilterButton = new Button(buttonContainer, SWT.PUSH);
fAddFilterButton.setText(Messages.pref_Add_filter);
fAddFilterButton.setToolTipText(Messages.pref_Add_filterTip);
gd = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
fAddFilterButton.setLayoutData(gd);
fAddFilterButton.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event e) {
editFilter();
}
});
// Remove button
fRemoveFilterButton = new Button(buttonContainer, SWT.PUSH);
fRemoveFilterButton.setText(Messages.pref_RemoveFilter);
fRemoveFilterButton.setToolTipText(Messages.pref_RemoveFilterTip);
gd = AnyEditPreferencePage.getButtonGridData(fRemoveFilterButton);
fRemoveFilterButton.setLayoutData(gd);
fRemoveFilterButton.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event e) {
removeFilters();
}
});
fRemoveFilterButton.setEnabled(false);
fEnableAllButton = new Button(buttonContainer, SWT.PUSH);
fEnableAllButton.setText(Messages.pref_Enable_all);
fEnableAllButton.setToolTipText(Messages.pref_Enable_allTip);
gd = AnyEditPreferencePage.getButtonGridData(fEnableAllButton);
fEnableAllButton.setLayoutData(gd);
fEnableAllButton.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event e) {
checkAllFilters(true);
}
});
fDisableAllButton = new Button(buttonContainer, SWT.PUSH);
fDisableAllButton.setText(Messages.pref_Disable_all);
fDisableAllButton.setToolTipText(Messages.pref_Disable_allTip);
gd = AnyEditPreferencePage.getButtonGridData(fDisableAllButton);
fDisableAllButton.setLayoutData(gd);
fDisableAllButton.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event e) {
checkAllFilters(false);
}
});
}
protected void checkAllFilters(boolean check) {
Object[] filters = fStepFilterContentProvider.getElements(null);
for (int i = 0; i != filters.length; i++) {
((Filter) filters[i]).setChecked(check);
}
fFilterViewer.setAllChecked(check);
}
protected void removeFilters() {
IStructuredSelection selection = (IStructuredSelection) fFilterViewer
.getSelection();
fStepFilterContentProvider.removeFilters(selection.toArray());
}
/**
* Cleanup all widgetry & resources used by the in-place editing
*/
protected void cleanupEditor() {
if (fEditorText != null) {
fNewStepFilter = null;
fNewTableItem = null;
fTableEditor.setEditor(null, null, 0);
fEditorText.dispose();
fEditorText = null;
}
}
protected void removeNewFilter() {
fStepFilterContentProvider.removeFilters(new Object[] { fNewStepFilter });
}
/* @SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") */
protected void validateChangeAndCleanup() {
String trimmedValue = fEditorText.getText().trim();
// if the new value is blank, remove the filter
if (trimmedValue.length() < 1) {
removeNewFilter();
}
// if it's invalid, beep and leave sitting in the editor
else if (!AnyEditPreferencePage.validateEditorInput(trimmedValue)) {
fInvalidEditorText = trimmedValue;
fEditorText.setText(Messages.pref_Invalid_file_filter);
getShell().getDisplay().beep();
return;
// otherwise, commit the new value if not a duplicate
} else {
Object[] filters = fStepFilterContentProvider.getElements(null);
for (int i = 0; i < filters.length; i++) {
Filter filter = (Filter) filters[i];
if (filter.getName().equals(trimmedValue)) {
removeNewFilter();
cleanupEditor();
return;
}
}
fNewTableItem.setText(trimmedValue);
fNewStepFilter.setName(trimmedValue);
fFilterViewer.refresh();
}
cleanupEditor();
}
/**
* Create a new filter in the table (with the default 'new filter' value), then open
* up an in-place editor on it.
*/
protected void editFilter() {
// if a previous edit is still in progress, finish it
if (fEditorText != null) {
validateChangeAndCleanup();
}
fNewStepFilter = fStepFilterContentProvider.addFilter("", true);
fNewTableItem = fFilterTable.getItem(0);
// create & configure Text widget for editor
// Fix for bug 1766. Border behavior on for text fields varies per platform.
// On Motif, you always get a border, on other platforms,
// you don't. Specifying a border on Motif results in the characters
// getting pushed down so that only there very tops are visible. Thus,
// we have to specify different style constants for the different platforms.
int textStyles = SWT.SINGLE | SWT.LEFT;
if (!"motif".equals(SWT.getPlatform())) {
textStyles |= SWT.BORDER;
}
fEditorText = new Text(fFilterTable, textStyles);
GridData gd = new GridData(GridData.FILL_BOTH);
fEditorText.setLayoutData(gd);
// set the editor
fTableEditor.horizontalAlignment = SWT.LEFT;
fTableEditor.grabHorizontal = true;
fTableEditor.setEditor(fEditorText, fNewTableItem, 0);
// get the editor ready to use
fEditorText.setText(fNewStepFilter.getName());
fEditorText.selectAll();
setEditorListeners(fEditorText);
fEditorText.setFocus();
}
private void setEditorListeners(Text text) {
// CR means commit the changes, ESC means abort and don't commit
text.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent event) {
if (event.character == SWT.CR) {
if (fInvalidEditorText != null) {
String infoText = Messages.pref_Invalid_file_filter;
if (!fInvalidEditorText.equals(fEditorText.getText())
&& !infoText.equals(fEditorText.getText())) {
validateChangeAndCleanup();
} else {
fEditorText.setText(infoText);
}
fInvalidEditorText = null;
} else {
validateChangeAndCleanup();
}
} else if (event.character == SWT.ESC) {
removeNewFilter();
cleanupEditor();
}
}
});
// Consider loss of focus on the editor to mean the same as CR
text.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent event) {
if (fInvalidEditorText != null) {
String infoText = Messages.pref_Invalid_file_filter;
if (!fInvalidEditorText.equals(fEditorText.getText())
&& !infoText.equals(fEditorText.getText())) {
validateChangeAndCleanup();
} else {
fEditorText.setText(infoText);
}
fInvalidEditorText = null;
} else {
validateChangeAndCleanup();
}
}
});
// Consume traversal events from the text widget so that CR doesn't
// traverse away to dialog's default button. Without this, hitting
// CR in the text field closes the entire dialog.
text.addListener(SWT.Traverse, new Listener() {
@Override
public void handleEvent(Event event) {
event.doit = false;
}
});
}
protected void updateActions() {
if (fEnableAllButton != null) {
boolean enabled = fFilterViewer.getTable().getItemCount() > 0;
fEnableAllButton.setEnabled(enabled);
fDisableAllButton.setEnabled(enabled);
}
}
/**
* Content provider for the table. Content consists of instances of StepFilter.
*/
protected class FilterContentProvider implements IStructuredContentProvider {
private final CheckboxTableViewer fViewer;
private final List<Filter> fFilters;
public FilterContentProvider(CheckboxTableViewer viewer) {
fViewer = viewer;
List<String> active = createActiveStepFiltersList();
List<String> inactive = createInactiveStepFiltersList();
fFilters = new ArrayList<Filter>(active.size() + inactive.size());
populateList(inactive, false);
populateList(active, true);
updateActions();
}
public void setDefaults() {
fViewer.remove(fFilters.toArray());
List<String> defaultlist = createDefaultStepFiltersList();
fFilters.clear();
populateList(defaultlist, true);
}
protected final void populateList(List<String> list, boolean checked) {
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
addFilter(name, checked);
}
}
/**
* Returns a list of active step filters.
*
* @return list
*/
protected final List<String> createActiveStepFiltersList() {
IPreferenceStore defaultStore = AnyEditToolsPlugin.getDefault()
.getPreferenceStore();
String[] strings = EclipseUtils.parseList(prefs.get(
IAnyEditConstants.PREF_ACTIVE_FILTERS_LIST, defaultStore
.getString(IAnyEditConstants.PREF_ACTIVE_FILTERS_LIST)));
return Arrays.asList(strings);
}
/**
* Returns a list of active step filters.
*
* @return list
*/
protected List<String> createDefaultStepFiltersList() {
IPreferenceStore defaultStore = AnyEditToolsPlugin.getDefault()
.getPreferenceStore();
String[] strings = EclipseUtils.parseList(defaultStore
.getDefaultString(IAnyEditConstants.PREF_ACTIVE_FILTERS_LIST));
return Arrays.asList(strings);
}
/**
* Returns a list of active step filters.
*
* @return list
*/
protected final List<String> createInactiveStepFiltersList() {
IPreferenceStore defaultStore = AnyEditToolsPlugin.getDefault()
.getPreferenceStore();
String[] strings = EclipseUtils.parseList(prefs.get(
IAnyEditConstants.PREF_INACTIVE_FILTERS_LIST, defaultStore
.getString(IAnyEditConstants.PREF_INACTIVE_FILTERS_LIST)));
return Arrays.asList(strings);
}
public Filter addFilter(String name, boolean checked) {
Filter filter = new Filter(name, checked);
if (!fFilters.contains(filter)) {
fFilters.add(filter);
fViewer.add(filter);
fViewer.setChecked(filter, checked);
}
updateActions();
return filter;
}
public void saveFilters() {
int filtersSize = fFilters.size();
List<String> active = new ArrayList<String>(filtersSize);
List<String> inactive = new ArrayList<String>(filtersSize);
Iterator<Filter> iterator = fFilters.iterator();
while (iterator.hasNext()) {
Filter filter = iterator.next();
String name = filter.getName();
if (filter.isChecked()) {
active.add(name);
} else {
inactive.add(name);
}
}
String pref = AnyEditPreferencePage.serializeList(active
.toArray(new String[active.size()]));
prefs.put(IAnyEditConstants.PREF_ACTIVE_FILTERS_LIST, pref);
pref = AnyEditPreferencePage.serializeList(inactive
.toArray(new String[inactive.size()]));
prefs.put(IAnyEditConstants.PREF_INACTIVE_FILTERS_LIST, pref);
}
public void removeFilters(Object[] filters) {
for (int i = 0; i < filters.length; i++) {
Filter filter = (Filter) filters[i];
fFilters.remove(filter);
}
fViewer.remove(filters);
updateActions();
}
public void toggleFilter(Filter filter) {
boolean newState = !filter.isChecked();
filter.setChecked(newState);
fViewer.setChecked(filter, newState);
}
/**
* @see IStructuredContentProvider#getElements(Object)
*/
@Override
public Object[] getElements(Object inputElement) {
return fFilters.toArray();
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
/** ignored */
}
@Override
public void dispose() {
/** ignored */
}
}
private void createTabConvert() {
GridLayout layout;
GridData gridData;
TabItem tabManual = new TabItem(tabFolder, SWT.NONE);
tabManual.setText(Messages.pref_tab_convert);
Composite defPanel = AnyEditPreferencePage.createContainer(tabFolder);
tabManual.setControl(defPanel);
Group spacesComposite = new Group(defPanel, SWT.SHADOW_ETCHED_IN);
layout = new GridLayout();
spacesComposite.setLayout(layout);
gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL);
spacesComposite.setLayoutData(gridData);
spacesComposite.setText(Messages.pref_spacesIntro);
IPreferenceStore defaultStore = AnyEditToolsPlugin.getDefault()
.getPreferenceStore();
tabWidthText = AnyEditPreferencePage.createLabeledText(Messages.pref_tabWidth,
Messages.pref_tabWidthTip, prefs.get(IAnyEditConstants.EDITOR_TAB_WIDTH,
defaultStore.getDefaultString(IAnyEditConstants.EDITOR_TAB_WIDTH)),
spacesComposite, false, SWT.NONE);
tabWidthText.setTextLimit(2);
useJavaTabsCheck = AnyEditPreferencePage
.createLabeledCheck(
Messages.pref_javaTabWidthForJava,
Messages.pref_javaTabWidthForJavaTip,
prefs
.getBoolean(
IAnyEditConstants.USE_JAVA_TAB_WIDTH_FOR_JAVA,
defaultStore
.getDefaultBoolean(IAnyEditConstants.USE_JAVA_TAB_WIDTH_FOR_JAVA)),
spacesComposite);
useModulo4TabsCheck = AnyEditPreferencePage
.createLabeledCheck(
Messages.pref_useModulo4Tabs,
Messages.pref_useModulo4TabsTip,
prefs
.getBoolean(
IAnyEditConstants.USE_MODULO_CALCULATION_FOR_TABS_REPLACE,
defaultStore
.getDefaultBoolean(IAnyEditConstants.USE_MODULO_CALCULATION_FOR_TABS_REPLACE)),
spacesComposite);
removeTrailingSpacesCheck = AnyEditPreferencePage.createLabeledCheck(
Messages.pref_removeTrailingSpaces,
Messages.pref_removeTrailingSpacesTip, prefs.getBoolean(
IAnyEditConstants.REMOVE_TRAILING_SPACES, defaultStore
.getDefaultBoolean(IAnyEditConstants.REMOVE_TRAILING_SPACES)),
spacesComposite);
fixLineDelimitersCheck = AnyEditPreferencePage.createLabeledCheck(
Messages.pref_fixLineDelimiters,
Messages.pref_fixLineDelimitersTip, prefs.getBoolean(
IAnyEditConstants.FIX_LINE_DELIMITERS, defaultStore
.getDefaultBoolean(IAnyEditConstants.FIX_LINE_DELIMITERS)),
spacesComposite);
addNewLineCheck = AnyEditPreferencePage.createLabeledCheck(
Messages.pref_addNewline,
Messages.pref_addNewlineTip, prefs.getBoolean(
IAnyEditConstants.ADD_NEW_LINE, defaultStore
.getDefaultBoolean(IAnyEditConstants.ADD_NEW_LINE)),
spacesComposite);
replaceAllTabsCheck = AnyEditPreferencePage
.createLabeledCheck(
Messages.pref_replaceAllTabs,
Messages.pref_replaceAllTabsTip,
prefs
.getBoolean(
IAnyEditConstants.REPLACE_ALL_TABS_WITH_SPACES,
defaultStore
.getDefaultBoolean(IAnyEditConstants.REPLACE_ALL_TABS_WITH_SPACES)),
spacesComposite);
replaceAllSpacesCheck = AnyEditPreferencePage
.createLabeledCheck(
Messages.pref_replaceAllSpaces,
Messages.pref_replaceAllSpacesTip,
prefs
.getBoolean(
IAnyEditConstants.REPLACE_ALL_SPACES_WITH_TABS,
defaultStore
.getDefaultBoolean(IAnyEditConstants.REPLACE_ALL_SPACES_WITH_TABS)),
spacesComposite);
}
}