/******************************************************************************* | |
* Copyright (c) 2000, 2010 IBM Corporation, See4sys and others. | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v2.0 | |
* which accompanies this distribution, and is available at | |
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html | |
* | |
* Contributors: | |
* IBM Corporation - initial API and implementation | |
* See4sys - added support for problem markers on model objects (rather than | |
* only on workspace resources). Unfortunately, there was no other | |
* choice than copying the whole code from | |
* org.eclipse.ui.views.markers.internal for that purpose because | |
* many of the relevant classes, methods, and fields are private or | |
* package private. | |
*******************************************************************************/ | |
package org.eclipse.sphinx.emf.validation.ui.views; | |
import java.util.ArrayList; | |
import java.util.Collection; | |
import java.util.HashMap; | |
import java.util.List; | |
import org.eclipse.jface.dialogs.ErrorDialog; | |
import org.eclipse.jface.dialogs.IDialogConstants; | |
import org.eclipse.jface.dialogs.IInputValidator; | |
import org.eclipse.jface.dialogs.InputDialog; | |
import org.eclipse.jface.dialogs.TrayDialog; | |
import org.eclipse.jface.viewers.CheckStateChangedEvent; | |
import org.eclipse.jface.viewers.CheckboxTableViewer; | |
import org.eclipse.jface.viewers.CheckboxTreeViewer; | |
import org.eclipse.jface.viewers.ColumnWeightData; | |
import org.eclipse.jface.viewers.ICheckStateListener; | |
import org.eclipse.jface.viewers.ILabelProvider; | |
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.ITableLabelProvider; | |
import org.eclipse.jface.viewers.ITreeContentProvider; | |
import org.eclipse.jface.viewers.LabelProvider; | |
import org.eclipse.jface.viewers.SelectionChangedEvent; | |
import org.eclipse.jface.viewers.StructuredSelection; | |
import org.eclipse.jface.viewers.TableLayout; | |
import org.eclipse.jface.viewers.Viewer; | |
import org.eclipse.jface.viewers.ViewerComparator; | |
import org.eclipse.jface.window.Window; | |
import org.eclipse.osgi.util.NLS; | |
import org.eclipse.swt.SWT; | |
import org.eclipse.swt.events.SelectionAdapter; | |
import org.eclipse.swt.events.SelectionEvent; | |
import org.eclipse.swt.graphics.Image; | |
import org.eclipse.swt.graphics.Point; | |
import org.eclipse.swt.layout.GridData; | |
import org.eclipse.swt.layout.GridLayout; | |
import org.eclipse.swt.widgets.Button; | |
import org.eclipse.swt.widgets.Combo; | |
import org.eclipse.swt.widgets.Composite; | |
import org.eclipse.swt.widgets.Control; | |
import org.eclipse.swt.widgets.Label; | |
import org.eclipse.swt.widgets.Shell; | |
import org.eclipse.swt.widgets.Tree; | |
import org.eclipse.swt.widgets.TreeColumn; | |
import org.eclipse.ui.IWorkingSet; | |
import org.eclipse.ui.PlatformUI; | |
import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog; | |
/** | |
* Dialog which allows user to modify all settings of an org.eclipse.ui.views.MarkerFilter object. Not intended to be | |
* subclassed or instantiated by clients. | |
*/ | |
public abstract class DialogMarkerFilter extends TrayDialog { | |
static final int SELECT_ALL_FILTERS_ID = IDialogConstants.CLIENT_ID + 4; | |
static final int DESELECT_ALL_FILTERS_ID = IDialogConstants.CLIENT_ID + 5; | |
/** | |
* button IDs | |
*/ | |
static final int RESET_ID = IDialogConstants.CLIENT_ID; | |
static final int SELECT_WORKING_SET_ID = IDialogConstants.CLIENT_ID + 1; | |
static final int SELECT_ALL_ID = IDialogConstants.CLIENT_ID + 2; | |
static final int DESELECT_ALL_ID = IDialogConstants.CLIENT_ID + 3; | |
private class TypesLabelProvider extends LabelProvider implements ITableLabelProvider { | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int) | |
*/ | |
@Override | |
public Image getColumnImage(Object element, int columnIndex) { | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int) | |
*/ | |
@Override | |
public String getColumnText(Object element, int columnIndex) { | |
return ((AbstractNode) element).getName(); | |
} | |
} | |
/** | |
* Creates and manages a group of widgets for selecting a working set marker filter. | |
*/ | |
private class WorkingSetGroup { | |
private Button button; | |
private Button selectButton; | |
/** | |
* Creates the working set filter selection widgets. | |
* | |
* @param parent | |
* the parent composite of the working set widgets | |
*/ | |
WorkingSetGroup(Composite parent) { | |
// radio button has to be part of main radio button group | |
button = createRadioButton(parent, MarkerMessages.filtersDialog_noWorkingSet); | |
GridData data = new GridData(GridData.FILL_HORIZONTAL); | |
button.setLayoutData(data); | |
Composite composite = new Composite(parent, SWT.NONE); | |
composite.setFont(parent.getFont()); | |
GridLayout layout = new GridLayout(); | |
Button radio = new Button(parent, SWT.RADIO); | |
layout.marginWidth = radio.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; | |
layout.marginHeight = 0; | |
radio.dispose(); | |
composite.setLayout(layout); | |
selectButton = createButton(composite, SELECT_WORKING_SET_ID, MarkerMessages.filtersDialog_workingSetSelect, false); | |
} | |
/** | |
* Returns wether or not a working set filter should be used | |
* | |
* @return true=a working set filter should be used false=a working set filter should not be used | |
*/ | |
boolean getSelection() { | |
return button.getSelection(); | |
} | |
/** | |
* Returns the selected working set filter or null if none is selected. | |
* | |
* @return the selected working set filter or null if none is selected. | |
*/ | |
IWorkingSet getWorkingSet() { | |
return (IWorkingSet) button.getData(); | |
} | |
/** | |
* Sets the working set filter selection. | |
* | |
* @param selected | |
* true=a working set filter should be used false=no working set filter should be used | |
*/ | |
void setSelection(boolean selected) { | |
button.setSelection(selected); | |
if (selected) { | |
anyResourceButton.setSelection(false); | |
anyResourceInSameProjectButton.setSelection(false); | |
selectedResourceButton.setSelection(false); | |
selectedResourceAndChildrenButton.setSelection(false); | |
} | |
} | |
/** | |
* Opens the working set selection dialog. | |
*/ | |
void selectPressed() { | |
IWorkingSetSelectionDialog dialog = PlatformUI.getWorkbench().getWorkingSetManager().createWorkingSetSelectionDialog(getShell(), false); | |
IWorkingSet workingSet = getWorkingSet(); | |
if (workingSet != null) { | |
dialog.setSelection(new IWorkingSet[] { workingSet }); | |
} | |
if (dialog.open() == Window.OK) { | |
markDirty(); | |
IWorkingSet[] result = dialog.getSelection(); | |
if (result != null && result.length > 0) { | |
setWorkingSet(result[0]); | |
} else { | |
setWorkingSet(null); | |
} | |
if (getSelection() == false) { | |
setSelection(true); | |
} | |
} | |
} | |
/** | |
* Sets the specified working set. | |
* | |
* @param workingSet | |
* the working set | |
*/ | |
void setWorkingSet(IWorkingSet workingSet) { | |
button.setData(workingSet); | |
if (workingSet != null) { | |
button.setText(NLS.bind(MarkerMessages.filtersDialog_workingSet, workingSet.getLabel())); | |
} else { | |
button.setText(MarkerMessages.filtersDialog_noWorkingSet); | |
} | |
} | |
void setEnabled(boolean enabled) { | |
button.setEnabled(enabled); | |
selectButton.setEnabled(enabled); | |
} | |
} | |
/** | |
* AbstractNode is the abstract superclass of the node elements for MarkerTypes. | |
*/ | |
private abstract class AbstractNode { | |
/** | |
* Get the parent element of the receiver. | |
* | |
* @return Object | |
*/ | |
public abstract Object getParent(); | |
/** | |
* Get the name of the receiver. | |
* | |
* @return String | |
*/ | |
public abstract String getName(); | |
/** | |
* Return whether or not the receiver has children. | |
* | |
* @return boolean | |
*/ | |
public abstract boolean hasChildren(); | |
/** | |
* Get the children of the receiver. | |
* | |
* @return Object[] | |
*/ | |
public abstract Object[] getChildren(); | |
/** | |
* Return whether or not this is a category node. | |
* | |
* @return boolean | |
*/ | |
public abstract boolean isCategory(); | |
} | |
/** | |
* MarkerTypeNode is the wrapper for marker types. | |
*/ | |
private class MarkerTypeNode extends AbstractNode { | |
MarkerType type; | |
MarkerCategory category; | |
/** | |
* Create an instance of the receiver wrapping markerType. | |
* | |
* @param markerType | |
*/ | |
public MarkerTypeNode(MarkerType markerType) { | |
type = markerType; | |
nodeToTypeMapping.put(markerType.getId(), this); | |
} | |
/** | |
* Set the category of the receiver. | |
* | |
* @param category | |
*/ | |
public void setCategory(MarkerCategory category) { | |
this.category = category; | |
} | |
/** | |
* Get the category for the receiver. | |
* | |
* @return MarkerCategory | |
*/ | |
public MarkerCategory getCategory() { | |
return category; | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#getChildren() | |
*/ | |
@Override | |
public Object[] getChildren() { | |
return new Object[0]; | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#getParent() | |
*/ | |
@Override | |
public Object getParent() { | |
return category; | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#hasChildren() | |
*/ | |
@Override | |
public boolean hasChildren() { | |
return false; | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#getName() | |
*/ | |
@Override | |
public String getName() { | |
return type.getLabel(); | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#isCategory() | |
*/ | |
@Override | |
public boolean isCategory() { | |
return false; | |
} | |
/** | |
* Return the marker type this is wrapping | |
* | |
* @return Object | |
*/ | |
public Object getMarkerType() { | |
return type; | |
} | |
} | |
/** | |
* The MarkerCategory is a data type to represent the categories in the tree view. | |
*/ | |
private class MarkerCategory extends AbstractNode { | |
String name; | |
Collection<MarkerTypeNode> types = new ArrayList<MarkerTypeNode>(); | |
/** | |
* Create a new instance of the receiver with name categoryName. | |
* | |
* @param categoryName | |
*/ | |
public MarkerCategory(String categoryName) { | |
name = categoryName; | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#getName() | |
*/ | |
@Override | |
public String getName() { | |
return name; | |
} | |
/** | |
* Add markerType to the list of types. | |
* | |
* @param markerType | |
*/ | |
public void add(MarkerTypeNode markerType) { | |
types.add(markerType); | |
markerType.setCategory(this); | |
} | |
/** | |
* Return the marker types contained in the receiver. | |
* | |
* @return Object[] | |
*/ | |
public Object[] getMarkerTypes() { | |
return types.toArray(); | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#getChildren() | |
*/ | |
@Override | |
public Object[] getChildren() { | |
return getMarkerTypes(); | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#getParent() | |
*/ | |
@Override | |
public Object getParent() { | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#hasChildren() | |
*/ | |
@Override | |
public boolean hasChildren() { | |
return true; | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.ui.views.markers.internal.DialogMarkerFilter.AbstractNode#isCategory() | |
*/ | |
@Override | |
public boolean isCategory() { | |
return true; | |
} | |
} | |
private MarkerFilter[] filters; | |
private CheckboxTreeViewer typesViewer; | |
private Button anyResourceButton; | |
private Button anyResourceInSameProjectButton; | |
private Button selectedResourceButton; | |
private Button selectedResourceAndChildrenButton; | |
private Button selectAllButton; | |
private Button deselectAllButton; | |
private WorkingSetGroup workingSetGroup; | |
private boolean dirty = false; | |
private CheckboxTableViewer filtersList; | |
private MarkerFilter[] selectedFilters; | |
private HashMap<String, MarkerTypeNode> nodeToTypeMapping = new HashMap<String, MarkerTypeNode>(); | |
private ITreeContentProvider typesContentProvider; | |
/** | |
* Create a new instance of the receiver. | |
* | |
* @param parentShell | |
* @param filtersList | |
*/ | |
DialogMarkerFilter(Shell parentShell, MarkerFilter[] filtersList) { | |
super(parentShell); | |
setFilters(filtersList); | |
setShellStyle(getShellStyle() | SWT.RESIZE); | |
} | |
/** | |
* Set the filters in the filtersList by copying them. | |
* | |
* @param initialFilters | |
*/ | |
private void setFilters(MarkerFilter[] initialFilters) { | |
MarkerFilter[] newMarkers = new MarkerFilter[initialFilters.length]; | |
for (int i = 0; i < initialFilters.length; i++) { | |
MarkerFilter newFilter; | |
try { | |
newFilter = initialFilters[i].makeClone(); | |
} catch (CloneNotSupportedException exception) { | |
ErrorDialog.openError(getShell(), MarkerMessages.MarkerFilterDialog_errorTitle, | |
MarkerMessages.MarkerFilterDialog_failedFilterMessage, Util.errorStatus(exception)); | |
return; | |
} | |
newMarkers[i] = newFilter; | |
} | |
filters = newMarkers; | |
} | |
/* | |
* (non-Javadoc) Method declared on Dialog. | |
*/ | |
@Override | |
protected void buttonPressed(int buttonId) { | |
switch (buttonId) { | |
case RESET_ID: | |
resetPressed(); | |
markDirty(); | |
break; | |
case SELECT_WORKING_SET_ID: | |
workingSetGroup.selectPressed(); | |
break; | |
case SELECT_ALL_ID: | |
typesViewer.setAllChecked(true); | |
break; | |
case DESELECT_ALL_ID: | |
typesViewer.setAllChecked(false); | |
break; | |
case SELECT_ALL_FILTERS_ID: | |
filtersList.setAllChecked(true); | |
break; | |
case DESELECT_ALL_FILTERS_ID: | |
filtersList.setAllChecked(false); | |
break; | |
default: | |
break; | |
} | |
super.buttonPressed(buttonId); | |
} | |
/** | |
* Method declared on Window. | |
*/ | |
@Override | |
protected void configureShell(Shell newShell) { | |
super.configureShell(newShell); | |
newShell.setText(MarkerMessages.filtersDialog_title); | |
} | |
protected void createResetArea(Composite parent) { | |
Button reset = new Button(parent, SWT.PUSH); | |
reset.setText(MarkerMessages.restoreDefaults_text); | |
reset.setData(new Integer(RESET_ID)); | |
reset.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(SelectionEvent event) { | |
buttonPressed(((Integer) event.widget.getData()).intValue()); | |
} | |
}); | |
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END); | |
int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); | |
Point minSize = reset.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); | |
data.widthHint = Math.max(widthHint, minSize.x); | |
data.horizontalSpan = 2; | |
reset.setLayoutData(data); | |
} | |
/** | |
* Creates a check box button with the given parent and text. | |
* | |
* @param parent | |
* the parent composite | |
* @param text | |
* the text for the check box | |
* @param grabRow | |
* <code>true</code>to grab the remaining horizontal space, <code>false</code> otherwise | |
* @return the check box button | |
*/ | |
protected Button createCheckbox(Composite parent, String text, boolean grabRow) { | |
Button button = new Button(parent, SWT.CHECK); | |
if (grabRow) { | |
GridData gridData = new GridData(GridData.FILL_HORIZONTAL); | |
button.setLayoutData(gridData); | |
} | |
button.setText(text); | |
button.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(SelectionEvent e) { | |
updateForSelection(); | |
} | |
}); | |
button.setFont(parent.getFont()); | |
return button; | |
} | |
/** | |
* Creates a combo box with the given parent, items, and selection | |
* | |
* @param parent | |
* the parent composite | |
* @param items | |
* the items for the combo box | |
* @param selectionIndex | |
* the index of the item to select | |
* @return the combo box | |
*/ | |
protected Combo createCombo(Composite parent, String[] items, int selectionIndex) { | |
Combo combo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY); | |
combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); | |
combo.setFont(parent.getFont()); | |
combo.setItems(items); | |
combo.select(selectionIndex); | |
combo.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(SelectionEvent e) { | |
updateForSelection(); | |
} | |
}); | |
return combo; | |
} | |
/** | |
* Method declared on Dialog. | |
*/ | |
@Override | |
protected Control createDialogArea(Composite parent) { | |
Composite dialogArea = (Composite) super.createDialogArea(parent); | |
dialogArea.setLayout(new GridLayout(2, false)); | |
createFiltersArea(dialogArea); | |
Composite selectedComposite = createSelectedFilterArea(dialogArea); | |
selectedComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); | |
updateUIFromFilter(); | |
filtersList.setSelection(new StructuredSelection(filters[0])); | |
createResetArea(dialogArea); | |
createSeparatorLine(dialogArea); | |
applyDialogFont(dialogArea); | |
return dialogArea; | |
} | |
/** | |
* Create the list in the receiver. | |
* | |
* @param dialogArea | |
*/ | |
/** | |
* @param dialogArea | |
*/ | |
void createFiltersArea(Composite dialogArea) { | |
Composite listArea = new Composite(dialogArea, SWT.NONE); | |
listArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); | |
listArea.setLayout(new GridLayout()); | |
createUserFiltersArea(listArea); | |
createFilterSelectButtons(listArea); | |
} | |
/** | |
* Create the area for the user to select thier filters. | |
* | |
* @param listArea | |
*/ | |
void createUserFiltersArea(Composite listArea) { | |
Composite userComposite = new Composite(listArea, SWT.NONE); | |
userComposite.setLayout(new GridLayout(2, false)); | |
userComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); | |
Label title = new Label(userComposite, SWT.NONE); | |
title.setText(MarkerMessages.MarkerFilter_filtersTitle); | |
GridData titleData = new GridData(); | |
titleData.horizontalSpan = 2; | |
title.setLayoutData(titleData); | |
filtersList = CheckboxTableViewer.newCheckList(userComposite, SWT.BORDER); | |
filtersList.setContentProvider(new IStructuredContentProvider() { | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) | |
*/ | |
@Override | |
public Object[] getElements(Object inputElement) { | |
return filters; | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.viewers.IContentProvider#dispose() | |
*/ | |
@Override | |
public void dispose() { | |
// Do nothing | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, | |
* java.lang.Object, java.lang.Object) | |
*/ | |
@Override | |
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { | |
// Do nothing | |
} | |
}); | |
filtersList.setLabelProvider(new LabelProvider() { | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) | |
*/ | |
@Override | |
public String getText(Object element) { | |
return ((MarkerFilter) element).getName(); | |
} | |
}); | |
selectedFilters = new MarkerFilter[] { filters[0] }; | |
filtersList.setSelection(new StructuredSelection(selectedFilters)); | |
filtersList.addSelectionChangedListener(new ISelectionChangedListener() { | |
/* | |
* (non-Javadoc) | |
* @seeorg.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers. | |
* SelectionChangedEvent) | |
*/ | |
@Override | |
public void selectionChanged(SelectionChangedEvent event) { | |
updateFilterFromUI(); | |
setSelectedFilter(event); | |
} | |
}); | |
filtersList.setInput(this); | |
for (MarkerFilter element : filters) { | |
filtersList.setChecked(element, element.isEnabled()); | |
} | |
GridData listData = new GridData(SWT.FILL, SWT.FILL, true, true); | |
listData.widthHint = convertHorizontalDLUsToPixels(100); | |
filtersList.getControl().setLayoutData(listData); | |
Composite buttons = new Composite(userComposite, SWT.NONE); | |
GridLayout buttonLayout = new GridLayout(); | |
buttonLayout.marginWidth = 0; | |
buttons.setLayout(buttonLayout); | |
GridData buttonsData = new GridData(); | |
buttonsData.verticalAlignment = GridData.BEGINNING; | |
buttons.setLayoutData(buttonsData); | |
Button addNew = new Button(buttons, SWT.PUSH); | |
addNew.setText(MarkerMessages.MarkerFilter_addFilterName); | |
addNew.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(SelectionEvent e) { | |
InputDialog newDialog = new InputDialog(getShell(), MarkerMessages.MarkerFilterDialog_title, | |
MarkerMessages.MarkerFilterDialog_message, MarkerMessages.MarkerFilter_newFilterName, new IInputValidator() { | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.dialogs.IInputValidator#isValid(java.lang.String) | |
*/ | |
@Override | |
public String isValid(String newText) { | |
if (newText.length() == 0) { | |
return MarkerMessages.MarkerFilterDialog_emptyMessage; | |
} | |
for (MarkerFilter element : filters) { | |
if (element.getName().equals(newText)) { | |
return NLS.bind(MarkerMessages.filtersDialog_conflictingName, newText); | |
} | |
} | |
return null; | |
} | |
}); | |
newDialog.open(); | |
String newName = newDialog.getValue(); | |
if (newName != null) { | |
createNewFilter(newName); | |
} | |
} | |
}); | |
setButtonLayoutData(addNew); | |
Button remove = new Button(buttons, SWT.PUSH); | |
remove.setText(MarkerMessages.MarkerFilter_deleteSelectedName); | |
remove.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(SelectionEvent e) { | |
removeFilters(filtersList.getSelection()); | |
} | |
}); | |
setButtonLayoutData(remove); | |
} | |
/** | |
* Set the selected filter from event. | |
* | |
* @param event | |
*/ | |
protected void setSelectedFilter(SelectionChangedEvent event) { | |
ISelection selection = event.getSelection(); | |
if (selection instanceof IStructuredSelection) { | |
Collection list = ((IStructuredSelection) selection).toList(); | |
MarkerFilter[] selected = new MarkerFilter[list.size()]; | |
list.toArray(selected); | |
selectedFilters = selected; | |
} else { | |
selectedFilters = new MarkerFilter[0]; | |
} | |
updateUIFromFilter(); | |
} | |
/** | |
* Remove the filters in selection. | |
* | |
* @param selection | |
*/ | |
protected void removeFilters(ISelection selection) { | |
if (selection instanceof IStructuredSelection) { | |
List toRemove = ((IStructuredSelection) selection).toList(); | |
MarkerFilter[] newFilters = new MarkerFilter[filters.length - toRemove.size()]; | |
int index = 0; | |
for (MarkerFilter element : filters) { | |
if (toRemove.contains(element)) { | |
continue; | |
} | |
newFilters[index] = element; | |
index++; | |
} | |
filters = newFilters; | |
filtersList.refresh(); | |
updateUIFromFilter(); | |
} | |
} | |
/** | |
* Create a new filter called newName. | |
* | |
* @param newName | |
*/ | |
private void createNewFilter(String newName) { | |
MarkerFilter[] newFilters = new MarkerFilter[filters.length + 1]; | |
System.arraycopy(filters, 0, newFilters, 0, filters.length); | |
MarkerFilter filter = newFilter(newName); | |
newFilters[filters.length] = filter; | |
filters = newFilters; | |
filtersList.refresh(); | |
filtersList.setSelection(new StructuredSelection(filter), true); | |
filtersList.getControl().setFocus(); | |
} | |
/** | |
* Crate a newFilter called newName | |
* | |
* @param newName | |
* @return MarkerFilter | |
*/ | |
protected abstract MarkerFilter newFilter(String newName); | |
/** | |
* Create the area for the selected filter. | |
* | |
* @param composite | |
*/ | |
Composite createSelectedFilterArea(Composite composite) { | |
Composite selectedComposite = new Composite(composite, SWT.NONE); | |
selectedComposite.setLayout(new GridLayout(2, false)); | |
Composite leftComposite = new Composite(selectedComposite, SWT.NONE); | |
leftComposite.setLayout(new GridLayout()); | |
leftComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); | |
createResourceArea(leftComposite); | |
createAttributesArea(leftComposite); | |
Composite rightComposite = new Composite(selectedComposite, SWT.NONE); | |
createTypesArea(rightComposite); | |
rightComposite.setLayout(new GridLayout()); | |
rightComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); | |
return selectedComposite; | |
} | |
/** | |
* Creates a separator line above the OK/Cancel buttons bar | |
* | |
* @param parent | |
* the parent composite | |
*/ | |
protected void createSeparatorLine(Composite parent) { | |
// Build the separator line | |
Label separator = new Label(parent, SWT.HORIZONTAL | SWT.SEPARATOR); | |
GridData gd = new GridData(GridData.FILL_HORIZONTAL); | |
gd.horizontalSpan = 2; | |
separator.setLayoutData(gd); | |
} | |
/** | |
* Creates a radio button with the given parent and text. | |
* | |
* @param parent | |
* the parent composite | |
* @param text | |
* the text for the check box | |
* @return the radio box button | |
*/ | |
protected Button createRadioButton(Composite parent, String text) { | |
Button button = new Button(parent, SWT.RADIO); | |
button.setText(text); | |
button.setFont(parent.getFont()); | |
button.addSelectionListener(new SelectionAdapter() { | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) | |
*/ | |
@Override | |
public void widgetSelected(SelectionEvent e) { | |
updateForSelection(); | |
} | |
}); | |
return button; | |
} | |
/** | |
* Creates the area showing which resources should be considered. | |
* | |
* @param parent | |
* the parent composite | |
*/ | |
protected void createResourceArea(Composite parent) { | |
Composite group = new Composite(parent, SWT.NONE); | |
group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); | |
group.setLayout(new GridLayout()); | |
group.setFont(parent.getFont()); | |
anyResourceButton = createRadioButton(group, MarkerMessages.filtersDialog_anyResource); | |
anyResourceInSameProjectButton = createRadioButton(group, MarkerMessages.filtersDialog_anyResourceInSameProject); // added | |
// by | |
// cagatayk@acm.org | |
selectedResourceButton = createRadioButton(group, MarkerMessages.filtersDialog_selectedResource); | |
selectedResourceAndChildrenButton = createRadioButton(group, MarkerMessages.filtersDialog_selectedAndChildren); | |
workingSetGroup = new WorkingSetGroup(group); | |
} | |
/** | |
* Creates the area showing which marker types should be included. | |
* | |
* @param parent | |
* the parent composite | |
*/ | |
protected void createTypesArea(Composite parent) { | |
Composite composite = new Composite(parent, SWT.NONE); | |
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); | |
GridLayout layout = new GridLayout(); | |
composite.setLayout(layout); | |
Label label = new Label(composite, SWT.NONE); | |
label.setText(MarkerMessages.filtersDialog_showItemsOfType); | |
Tree tree = new Tree(composite, SWT.CHECK | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER); | |
tree.setLinesVisible(true); | |
tree.setHeaderVisible(false); | |
TableLayout tableLayout = new TableLayout(); | |
tree.setLayout(tableLayout); | |
tableLayout.addColumnData(new ColumnWeightData(100, true)); | |
new TreeColumn(tree, SWT.NONE, 0); | |
typesViewer = new CheckboxTreeViewer(tree); | |
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); | |
gridData.widthHint = convertVerticalDLUsToPixels(100); | |
gridData.heightHint = convertVerticalDLUsToPixels(125); | |
typesContentProvider = getTypesContentProvider(); | |
typesViewer.getControl().setLayoutData(gridData); | |
typesViewer.setContentProvider(typesContentProvider); | |
typesViewer.setLabelProvider(getLabelProvider()); | |
typesViewer.setComparator(getComparator()); | |
typesViewer.addCheckStateListener(new ICheckStateListener() { | |
@Override | |
public void checkStateChanged(CheckStateChangedEvent event) { | |
markDirty(); | |
Object element = event.getElement(); | |
boolean checked = event.getChecked(); | |
setChildrenChecked(element, checked); | |
setParentCheckState(element, checked); | |
} | |
}); | |
typesViewer.setInput(getSelectedFilter().getRootTypes().toArray()); | |
Composite buttonComposite = new Composite(composite, SWT.NONE); | |
GridLayout buttonLayout = new GridLayout(); | |
buttonLayout.marginWidth = 0; | |
buttonComposite.setLayout(buttonLayout); | |
selectAllButton = createButton(buttonComposite, SELECT_ALL_ID, MarkerMessages.filtersDialog_selectAllTypes, false); | |
deselectAllButton = createButton(buttonComposite, DESELECT_ALL_ID, MarkerMessages.filtersDialog_deselectAllTypes, false); | |
} | |
/** | |
* Get the currently selected marker filter if there is only one selection. | |
* | |
* @return MarkerFilter or <code>null</code>. | |
*/ | |
protected MarkerFilter getSelectedFilter() { | |
if (selectedFilters.length == 1) { | |
return selectedFilters[0]; | |
} | |
return null; | |
} | |
/** | |
* Get the content provider for the receiver. | |
* | |
* @return ITreeContentProvider | |
*/ | |
private ITreeContentProvider getTypesContentProvider() { | |
return new ITreeContentProvider() { | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) | |
*/ | |
@Override | |
public Object[] getElements(Object inputElement) { | |
MarkerFilter selected = getSelectedFilter(); | |
if (selected == null) { | |
return new Object[0]; | |
} | |
return getRootEntries(selected); | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.viewers.IContentProvider#dispose() | |
*/ | |
@Override | |
public void dispose() { | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, | |
* java.lang.Object, java.lang.Object) | |
*/ | |
@Override | |
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) | |
*/ | |
@Override | |
public Object[] getChildren(Object parentElement) { | |
return ((AbstractNode) parentElement).getChildren(); | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) | |
*/ | |
@Override | |
public Object getParent(Object element) { | |
return ((AbstractNode) element).getParent(); | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) | |
*/ | |
@Override | |
public boolean hasChildren(Object element) { | |
return ((AbstractNode) element).hasChildren(); | |
} | |
}; | |
} | |
/** | |
* This method is intended to be overridden by subclasses of FiltersDialog. The attributes area will be created just | |
* above the Restore Defaults button. | |
* | |
* @param parent | |
* the parent Composite | |
*/ | |
abstract void createAttributesArea(Composite parent); | |
private ILabelProvider getLabelProvider() { | |
return new TypesLabelProvider(); | |
} | |
/** | |
* Returns the selected marker types. | |
* | |
* @return List the selected marker types | |
*/ | |
protected List getSelectedTypes() { | |
Object[] checkElements = typesViewer.getCheckedElements(); | |
List selected = new ArrayList(); | |
for (Object element : checkElements) { | |
AbstractNode node = (AbstractNode) element; | |
if (!node.isCategory()) { | |
selected.add(((MarkerTypeNode) node).getMarkerType()); | |
} | |
} | |
return selected; | |
} | |
/** | |
* Return the sorter for the receiver. | |
* | |
* @return ViewerSorter | |
*/ | |
protected ViewerComparator getComparator() { | |
return new ViewerComparator() { | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, | |
* java.lang.Object, java.lang.Object) | |
*/ | |
@Override | |
public int compare(Viewer viewer, Object e1, Object e2) { | |
return getComparator().compare(((AbstractNode) e1).getName(), ((AbstractNode) e2).getName()); | |
} | |
}; | |
} | |
/* | |
* (non-Javadoc) | |
* @see org.eclipse.jface.dialogs.Dialog#okPressed() | |
*/ | |
@Override | |
protected void okPressed() { | |
/** | |
* Updates the filter from the UI state. Must be done here rather than by extending open() because after | |
* super.open() is called, the widgetry is disposed. | |
*/ | |
updateFilterFromUI(); | |
for (MarkerFilter element : filters) { | |
element.setEnabled(filtersList.getChecked(element)); | |
} | |
super.okPressed(); | |
} | |
/** | |
* Handles a press of the Reset button. Updates the UI state to correspond to a reset filter, but doesn't actually | |
* reset our filter. | |
*/ | |
protected void resetPressed() { | |
typesViewer.setAllChecked(true); | |
int onResource = MarkerFilter.DEFAULT_ON_RESOURCE; | |
anyResourceButton.setSelection(onResource == MarkerFilter.ON_ANY); | |
anyResourceInSameProjectButton.setSelection(onResource == MarkerFilter.ON_ANY_IN_SAME_CONTAINER); | |
selectedResourceButton.setSelection(onResource == MarkerFilter.ON_SELECTED_ONLY); | |
selectedResourceAndChildrenButton.setSelection(onResource == MarkerFilter.ON_SELECTED_AND_CHILDREN); | |
workingSetGroup.setSelection(onResource == MarkerFilter.ON_WORKING_SET); | |
updateEnabledState(true); | |
} | |
/** | |
* Sets the selected marker types. | |
* | |
* @param markerTypes | |
*/ | |
void setSelectedTypes(List markerTypes) { | |
typesViewer.setCheckedElements(new Object[0]); | |
for (int i = 0; i < markerTypes.size(); i++) { | |
Object obj = markerTypes.get(i); | |
if (obj instanceof MarkerType) { | |
Object mapping = nodeToTypeMapping.get(((MarkerType) obj).getId()); | |
if (mapping != null) { | |
typesViewer.setChecked(mapping, true); | |
setParentCheckState(mapping, true); | |
} | |
} | |
} | |
} | |
/** | |
* Updates the enabled state of the widgetry based on whether or not it is enabled. | |
*/ | |
protected void updateEnabledState(boolean enabled) { | |
typesViewer.getTree().setEnabled(enabled); | |
selectAllButton.setEnabled(enabled && typesViewer.getTree().getItemCount() > 0); | |
deselectAllButton.setEnabled(enabled && typesViewer.getTree().getItemCount() > 0); | |
anyResourceButton.setEnabled(enabled); | |
anyResourceInSameProjectButton.setEnabled(enabled); | |
selectedResourceButton.setEnabled(enabled); | |
selectedResourceAndChildrenButton.setEnabled(enabled); | |
workingSetGroup.setEnabled(enabled); | |
} | |
/** | |
* Updates the given filter from the UI state. | |
*/ | |
protected final void updateFilterFromUI() { | |
MarkerFilter filter = getSelectedFilter(); | |
if (filter == null) { | |
updateEnabledState(false); | |
return; | |
} | |
updateFilterFromUI(filter); | |
} | |
/** | |
* Update the selected filter from the UI. | |
* | |
* @param filter | |
*/ | |
protected void updateFilterFromUI(MarkerFilter filter) { | |
filter.setSelectedTypes(getSelectedTypes()); | |
if (selectedResourceButton.getSelection()) { | |
filter.setOnResource(MarkerFilter.ON_SELECTED_ONLY); | |
} else if (selectedResourceAndChildrenButton.getSelection()) { | |
filter.setOnResource(MarkerFilter.ON_SELECTED_AND_CHILDREN); | |
} else if (anyResourceInSameProjectButton.getSelection()) { | |
filter.setOnResource(MarkerFilter.ON_ANY_IN_SAME_CONTAINER); | |
} else if (workingSetGroup.getSelection()) { | |
filter.setOnResource(MarkerFilter.ON_WORKING_SET); | |
} else { | |
filter.setOnResource(MarkerFilter.ON_ANY); | |
} | |
filter.setWorkingSet(workingSetGroup.getWorkingSet()); | |
} | |
/** | |
* Updates the UI state from the given filter. | |
*/ | |
protected final void updateUIFromFilter() { | |
MarkerFilter filter = getSelectedFilter(); | |
if (filter == null) { | |
updateEnabledState(false); | |
return; | |
} | |
updateUIWithFilter(filter); | |
} | |
/** | |
* Update the UI with the contents of filter. | |
* | |
* @param filter | |
*/ | |
protected void updateUIWithFilter(MarkerFilter filter) { | |
setSelectedTypes(filter.getSelectedTypes()); | |
int on = filter.getOnResource(); | |
anyResourceButton.setSelection(on == MarkerFilter.ON_ANY); | |
anyResourceInSameProjectButton.setSelection(on == MarkerFilter.ON_ANY_IN_SAME_CONTAINER); | |
selectedResourceButton.setSelection(on == MarkerFilter.ON_SELECTED_ONLY); | |
selectedResourceAndChildrenButton.setSelection(on == MarkerFilter.ON_SELECTED_AND_CHILDREN); | |
workingSetGroup.setSelection(on == MarkerFilter.ON_WORKING_SET); | |
workingSetGroup.setWorkingSet(filter.getWorkingSet()); | |
updateEnabledState(true); | |
} | |
/** | |
* @return <code>true</code> if the dirty flag has been set otherwise <code>false</code>. | |
*/ | |
boolean isDirty() { | |
return dirty; | |
} | |
/** | |
* Marks the dialog as dirty. | |
*/ | |
void markDirty() { | |
dirty = true; | |
} | |
/** | |
* Set the marker filter. | |
* | |
* @param newFilter | |
*/ | |
public void setFilter(MarkerFilter newFilter) { | |
setFilters(new MarkerFilter[] { newFilter }); | |
updateUIFromFilter(); | |
} | |
/** | |
* @return the MarkerFilters associated with the dialog. | |
*/ | |
public MarkerFilter[] getFilters() { | |
return filters; | |
} | |
/** | |
* A selection has occured on one of the checkboxes or combos. Update. | |
*/ | |
protected void updateForSelection() { | |
updateEnabledState(true); | |
markDirty(); | |
} | |
/** | |
* Get all of the marker types avilable for the filter | |
* | |
* @param selected | |
* @return Object[] | |
*/ | |
Object[] getRootEntries(MarkerFilter selected) { | |
List roots = selected.getRootTypes(); | |
List markerNodes = new ArrayList(); | |
HashMap categories = new HashMap(); | |
for (int i = 0; i < roots.size(); i++) { | |
Object obj = roots.get(i); | |
buildTypeTree(markerNodes, obj, categories); | |
} | |
return markerNodes.toArray(); | |
} | |
/** | |
* Build the list of types and categories from the supplied object | |
* | |
* @param elements | |
* @param obj | |
* @param categories | |
*/ | |
private void buildTypeTree(List elements, Object obj, HashMap categories) { | |
if (obj instanceof MarkerType) { | |
MarkerType markerType = (MarkerType) obj; | |
String categoryName = MarkerSupportRegistry.getInstance().getCategory(markerType.getId()); | |
if (categoryName == null) { | |
elements.add(new MarkerTypeNode(markerType)); | |
} else { | |
MarkerCategory category; | |
if (categories.containsKey(categoryName)) { | |
category = (MarkerCategory) categories.get(categoryName); | |
} else { | |
category = new MarkerCategory(categoryName); | |
categories.put(categoryName, category); | |
elements.add(category); | |
} | |
MarkerTypeNode node = new MarkerTypeNode(markerType); | |
category.add(node); | |
} | |
MarkerType[] subTypes = ((MarkerType) obj).getSubtypes(); | |
for (MarkerType element : subTypes) { | |
buildTypeTree(elements, element, categories); | |
} | |
} | |
} | |
/** | |
* Grey check the parent if required | |
* | |
* @param element | |
* @param checked | |
*/ | |
private void setParentCheckState(Object element, boolean checked) { | |
Object parent = typesContentProvider.getParent(element); | |
if (parent == null) { | |
return; | |
} | |
Object[] children = typesContentProvider.getChildren(parent); | |
if (children.length == 0) { | |
return; | |
} | |
if (checked) {// at least one is checked | |
for (Object object : children) { | |
if (!typesViewer.getChecked(object)) { | |
typesViewer.setGrayChecked(parent, true); | |
return; | |
} | |
} | |
// All checked - check the parent | |
typesViewer.setChecked(parent, true); | |
} else { | |
for (Object object : children) { | |
if (typesViewer.getChecked(object)) { | |
typesViewer.setGrayChecked(parent, true); | |
return; | |
} | |
} | |
// All checked - check the parent | |
typesViewer.setChecked(parent, false); | |
} | |
} | |
/** | |
* Set the check state of the children of element to checked. | |
* | |
* @param element | |
* @param checked | |
*/ | |
private void setChildrenChecked(Object element, boolean checked) { | |
Object[] children = typesContentProvider.getChildren(element); | |
if (children.length > 0) { | |
for (Object element2 : children) { | |
typesViewer.setChecked(element2, checked); | |
} | |
} | |
} | |
/** | |
* Create the buttons for selecting the filters. | |
* | |
* @param listArea | |
*/ | |
protected void createFilterSelectButtons(Composite listArea) { | |
Composite buttons = new Composite(listArea, SWT.NONE); | |
GridLayout buttonLayout = new GridLayout(2, false); | |
buttonLayout.marginWidth = 0; | |
buttons.setLayout(buttonLayout); | |
createButton(buttons, SELECT_ALL_FILTERS_ID, MarkerMessages.filtersDialog_selectAll, false); | |
createButton(buttons, DESELECT_ALL_FILTERS_ID, MarkerMessages.filtersDialog_deselectAll, false); | |
} | |
} |