/* * Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.tools.search2.internal.ui; import com.google.dart.tools.search.internal.ui.SearchPlugin; import com.google.dart.tools.search.ui.NewSearchUI; import com.google.dart.tools.search.ui.text.MatchFilter; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.StatusDialog; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; 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.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.Text; /** * A dialog that lets users configure the active {@link MatchFilter match filters} and (optionally) * the maximal number of top level elements. */ public class MatchFilterSelectionDialog extends StatusDialog { private final boolean fShowLimitConfigurationControls; private final MatchFilter[] fAllFilters; private MatchFilter[] fEnabledFilters; private CheckboxTableViewer fListViewer; private Button fLimitElementsCheckbox; private Text fLimitElementsField; private Text fDescription; private int fLimitElementCount; private int fLastLimit; private final boolean fEnableMatchFilterConfiguration; /** * Creates a {@link MatchFilterSelectionDialog}. * * @param shell the parent shell * @param enableMatchFilterConfiguration <code>true</code> if match filter configuration should be * enabled * @param allFilters all filters available for selection * @param selectedFilters the initially selected filters * @param enableLimitConfiguration if set, the dialog will also contain controls to limit the * number of top level elements * @param limit the initial limit or -1 if no limit should be used. */ public MatchFilterSelectionDialog(Shell shell, boolean enableMatchFilterConfiguration, MatchFilter[] allFilters, MatchFilter[] selectedFilters, boolean enableLimitConfiguration, int limit) { super(shell); setTitle(SearchMessages.MatchFilterSelectionDialog_label); setStatusLineAboveButtons(true); fShowLimitConfigurationControls = enableLimitConfiguration; fEnableMatchFilterConfiguration = enableMatchFilterConfiguration; fAllFilters = allFilters; fEnabledFilters = selectedFilters; fLimitElementCount = limit; fLastLimit = limit != -1 ? limit : 1000; } protected boolean isResizable() { return true; } protected IDialogSettings getDialogBoundsSettings() { String name = "MatchFilterSelectionDialog_" + String.valueOf(fShowLimitConfigurationControls) + '.' + String.valueOf(fEnableMatchFilterConfiguration); //$NON-NLS-1$ return SearchPlugin.getDefault().getDialogSettingsSection(name); } /** * Returns the currently selected match filters. * * @return the currently selected match filters. */ public MatchFilter[] getMatchFilters() { return fEnabledFilters; } /** * Returns the currently configured limit for top level elements. <code>-1</code> is returned if * no limit should be applied. * * @return the currently configured limit for top level elements or -1 if no limit should be used. */ public int getLimit() { return fLimitElementCount; } protected Control createDialogArea(Composite composite) { Composite parent = (Composite) super.createDialogArea(composite); initializeDialogUnits(composite); if (fShowLimitConfigurationControls) { createTableLimit(parent); } if (fEnableMatchFilterConfiguration) { createMatchFilterControls(parent); } return parent; } private void createMatchFilterControls(Composite parent) { // Create list viewer Label l = new Label(parent, SWT.NONE); l.setFont(parent.getFont()); l.setText(SearchMessages.MatchFilterSelectionDialog_filter_description); Table table = new Table(parent, SWT.CHECK | SWT.BORDER); table.setFont(parent.getFont()); fListViewer = new CheckboxTableViewer(table); GridData data = new GridData(GridData.FILL_BOTH); data.minimumHeight = convertHeightInCharsToPixels(8); table.setLayoutData(data); class ListenerAndLabelProvider extends LabelProvider implements ISelectionChangedListener, ICheckStateListener { public void selectionChanged(SelectionChangedEvent event) { performFilterListSelectionChanged(); } public void checkStateChanged(CheckStateChangedEvent event) { performFilterListCheckStateChanged(); } public String getText(Object element) { return ((MatchFilter) element).getName(); } } ListenerAndLabelProvider listenerAndLP = new ListenerAndLabelProvider(); fListViewer.setLabelProvider(listenerAndLP); fListViewer.setContentProvider(new ArrayContentProvider()); fListViewer.addSelectionChangedListener(listenerAndLP); fListViewer.addCheckStateListener(listenerAndLP); fListViewer.setInput(fAllFilters); fListViewer.setCheckedElements(fEnabledFilters); l = new Label(parent, SWT.NONE); l.setFont(parent.getFont()); l.setText(SearchMessages.MatchFilterSelectionDialog_description_label); fDescription = new Text(parent, SWT.LEFT | SWT.WRAP | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.V_SCROLL); fDescription.setFont(parent.getFont()); data = new GridData(GridData.FILL_HORIZONTAL); data.heightHint = convertHeightInCharsToPixels(3); fDescription.setLayoutData(data); } private void createTableLimit(Composite ancestor) { Composite parent = new Composite(ancestor, SWT.NONE); parent.setFont(ancestor.getFont()); GridLayout gl = new GridLayout(); gl.numColumns = 2; gl.marginWidth = 0; gl.marginHeight = 0; parent.setLayout(gl); GridData gd = new GridData(); gd.horizontalSpan = 2; parent.setLayoutData(gd); fLimitElementsCheckbox = new Button(parent, SWT.CHECK); fLimitElementsCheckbox.setText(SearchMessages.MatchFilterSelectionDialog_limit_description); fLimitElementsCheckbox.setLayoutData(new GridData()); fLimitElementsCheckbox.setFont(parent.getFont()); fLimitElementsField = new Text(parent, SWT.BORDER); fLimitElementsField.setFont(parent.getFont()); gd = new GridData(); gd.widthHint = convertWidthInCharsToPixels(6); fLimitElementsField.setLayoutData(gd); fLimitElementsCheckbox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { performLimitCheckboxChanged(); } }); fLimitElementsField.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { performLimitTextModified(); } }); fLimitElementsCheckbox.setSelection(fLimitElementCount != -1); fLimitElementsField.setText(String.valueOf(fLastLimit)); fLimitElementsField.setEnabled(fLimitElementsCheckbox.getSelection()); } private void performFilterListSelectionChanged() { Object selectedElement = ((IStructuredSelection) fListViewer.getSelection()).getFirstElement(); if (selectedElement != null) fDescription.setText(((MatchFilter) selectedElement).getDescription()); else fDescription.setText(new String()); } private void performFilterListCheckStateChanged() { Object[] checked = fListViewer.getCheckedElements(); fEnabledFilters = new MatchFilter[checked.length]; System.arraycopy(checked, 0, fEnabledFilters, 0, checked.length); } private void performLimitCheckboxChanged() { boolean isEnabled = fLimitElementsCheckbox.getSelection(); fLimitElementsField.setEnabled(isEnabled); if (isEnabled) { fLimitElementCount = fLastLimit; } else { fLastLimit = fLimitElementCount; fLimitElementCount = -1; } } private void performLimitTextModified() { String text = fLimitElementsField.getText(); int value = -1; try { value = Integer.valueOf(text).intValue(); } catch (NumberFormatException e) { } fLimitElementCount = value; if (fLimitElementsCheckbox.getSelection() && value <= 0) updateStatus(createStatus( IStatus.ERROR, SearchMessages.MatchFilterSelectionDialog_error_invalid_limit)); else updateStatus(createStatus(IStatus.OK, "")); //$NON-NLS-1$ } private IStatus createStatus(int severity, String message) { return new Status(severity, NewSearchUI.PLUGIN_ID, severity, message, null); } }