/******************************************************************************* * Copyright (c) 2012 Arapiki Solutions Inc. * 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: * "Peter Smith <psmith@arapiki.com>" - initial API and * implementation and/or initial documentation *******************************************************************************/ package com.buildml.eclipse.utils; import org.eclipse.jface.dialogs.IDialogConstants; 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.Shell; import org.eclipse.swt.widgets.Text; /** * A Dialog allowing the user to select a regular expression to match a file/action name. * The user may also determine whether the matching files/actions should be added to, * or extracted from the current set of items displayed. * * @author "Peter Smith <psmith@arapiki.com>" */ public class NameFilterDialog extends BmlTitleAreaDialog { /*=====================================================================================* * FIELDS/TYPES *=====================================================================================*/ /** A constant representing the radio button state: "select only matching items." */ public static final int SELECT_ONLY_MATCHING_ITEMS = 0; /** A constant representing the radio button state: "add matching items to existing." */ public static final int ADD_MATCHING_ITEMS = 1; /** A constant representing the radio button state: "remove matching items from existing." */ public static final int REMOVE_MATCHING_ITEMS = 2; /** A constant representing the radio button state: "select all items" */ public static final int SELECT_ALL_ITEMS = 3; /** A constant representing the radio button state: "deselect all items" */ public static final int DESELECT_ALL_ITEMS = 4; /** The text box into which the regular expression is entered. */ private Text textBox = null; /** The text, saved at the point the "OK" button is pressed */ private String enteredText = null; /** The radio button state, saved at the point the "OK" button is pressed */ private int radioButtonState = SELECT_ONLY_MATCHING_ITEMS; /** The string name of the type of item being selected (e.g. "files" or "actions"). */ private String itemType; /** The version of itemType with the first letter capitalized. (e.g. "Files" or "Actions") */ private String upperItemType; /*=====================================================================================* * CONSTRUCTOR *=====================================================================================*/ /** * Create a new NameFilterDialog instance. This allows the user to enter a regular * expression to filter the name of something. * @param itemType The name of the item being selected (e.g. "files" or "actions"). */ public NameFilterDialog(String itemType) { super(new Shell(), 0, 0, 0, 0); this.itemType = itemType; this.upperItemType = itemType.substring(0, 1).toUpperCase() + itemType.substring(1); } /*=====================================================================================* * PUBLIC METHODS *=====================================================================================*/ /** * @return The regular expression, as entered by the user. */ public String getRegularExpression() { return enteredText; } /*-------------------------------------------------------------------------------------*/ /** * Return the select that the user made in the "add" or "remove" radio buttons. * @return NameFilterDialog.ADD_ITEMS if "add" was selected, else NameFilterDialog.REMOVE_ITEMS. */ public int getAddRemoveChoice() { return radioButtonState; } /*-------------------------------------------------------------------------------------*/ /* (non-Javadoc) * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) */ @Override protected Control createDialogArea(Composite parent) { setTitle("Enter a pattern to select " + itemType + " (using * to match multiple characters):"); setHelpAvailable(false); /* create and format the top-level composite of this dialog */ Composite composite = new Composite( (Composite)super.createDialogArea(parent), SWT.None); composite.setLayout(new GridLayout()); GridData compositeGridData = new GridData(SWT.FILL, SWT.FILL, true, true); composite.setLayoutData(compositeGridData); /* * Add all the radio buttons, for the various ways to select data. */ Button firstButton = addRadioOption(composite, true, SELECT_ONLY_MATCHING_ITEMS, "Select only the " + itemType + " that match this pattern."); addRadioOption(composite, true, ADD_MATCHING_ITEMS, "Add matching " + itemType + " to the existing selection."); addRadioOption(composite, true, REMOVE_MATCHING_ITEMS, "Remove matching " + itemType + " from the existing selection."); addRadioOption(composite, false, SELECT_ALL_ITEMS, "Add all " + itemType + " to the selection."); addRadioOption(composite, false, DESELECT_ALL_ITEMS, "Remove all " + itemType + " from the selection."); /* Add a text entry box, that the user enters the expression into */ textBox = new Text(composite, SWT.SINGLE | SWT.BORDER); GridData gridData = new GridData(SWT.FILL, SWT.NONE, true, false); gridData.verticalIndent = 10; textBox.setLayoutData(gridData); /* fix the vertical indent for the first item in our list of radio buttons */ firstButton.setSelection(true); gridData = (GridData)firstButton.getLayoutData(); gridData.verticalIndent = 10; /* un-disable the OK button, once some text is entered */ textBox.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { getButton(OK).setEnabled(!textBox.getText().isEmpty()); } }); textBox.setFocus(); return composite; } /*-------------------------------------------------------------------------------------*/ /* (non-Javadoc) * @see org.eclipse.jface.dialogs.Dialog#okPressed() */ @Override protected void okPressed() { /* save the state of the dialog, so our creator can access it later */ enteredText = textBox.getText(); /* now dispose the window */ super.okPressed(); } /*-------------------------------------------------------------------------------------*/ /* * (non-Javadoc) * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) */ @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText("Select " + upperItemType + " to Display in Editor."); } /*-------------------------------------------------------------------------------------*/ /* (non-Javadoc) * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite) */ @Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, "Select", true); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); /* disable the OK button by default, until some text is entered */ getButton(OK).setEnabled(false); } /*-------------------------------------------------------------------------------------*/ /** * Create a new radio-style button, with the associated text label. When the radio * button is selected, that specific option will be set as the value to be returned * by getAddRemoveChoice(). * * @param composite The parent widget we're adding the radio button to. * @param requiresTextBox True if the text box is required for this option, else false. * @param selectedButtonIndex The value to be returned by getAddRemoveChoice(). * @param label The textual label to display next to the radio button. * @return The newly created Button widget. */ private Button addRadioOption(Composite composite, final boolean requiresTextBox, final int selectedButtonIndex, String label) { final Button newButton = new Button(composite, SWT.RADIO); newButton.setText(label); GridData gridData = new GridData(); newButton.setLayoutData(gridData); /* * Add a listener for this radio button. Depending on the radio button chosen, * we may (or may not) want to enable the text box entry. */ newButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { /* was the radio button recently selected? */ if (newButton.getSelection()) { radioButtonState = selectedButtonIndex; /* does this option require a (non-empty) text box field? */ if (requiresTextBox) { textBox.setEnabled(true); getButton(OK).setEnabled(!textBox.getText().isEmpty()); } /* or is no text box input required? */ else { textBox.setEnabled(false); getButton(OK).setEnabled(true); } } } }); return newButton; } /*-------------------------------------------------------------------------------------*/ }