1 package net.sourceforge.phpdt.internal.ui.dialogs;
3 import net.sourceforge.phpdt.internal.ui.util.FilteredList;
5 import org.eclipse.core.runtime.IStatus;
6 import org.eclipse.jface.dialogs.IDialogConstants;
8 //import org.eclipse.jface.text.Assert;
9 import org.eclipse.core.runtime.Assert;
10 import org.eclipse.jface.viewers.ILabelProvider;
11 import org.eclipse.swt.SWT;
12 import org.eclipse.swt.custom.BusyIndicator;
13 import org.eclipse.swt.events.KeyEvent;
14 import org.eclipse.swt.events.KeyListener;
15 import org.eclipse.swt.events.SelectionEvent;
16 import org.eclipse.swt.events.SelectionListener;
17 import org.eclipse.swt.layout.GridData;
18 import org.eclipse.swt.widgets.Composite;
19 import org.eclipse.swt.widgets.Event;
20 import org.eclipse.swt.widgets.Label;
21 import org.eclipse.swt.widgets.Listener;
22 import org.eclipse.swt.widgets.Shell;
23 import org.eclipse.swt.widgets.Text;
26 * An abstract class to select elements out of a list of elements.
28 public abstract class AbstractElementListSelectionDialog extends
29 SelectionStatusDialog {
31 private ILabelProvider fRenderer;
33 private boolean fIgnoreCase = true;
35 private boolean fIsMultipleSelection = false;
37 private boolean fMatchEmptyString = true;
39 private boolean fAllowDuplicates = true;
41 private Label fMessage;
43 protected FilteredList fFilteredList;
45 private Text fFilterText;
47 private ISelectionValidator fValidator;
49 private String fFilter = null;
51 private String fEmptyListMessage = ""; //$NON-NLS-1$
53 private String fEmptySelectionMessage = ""; //$NON-NLS-1$
55 private int fWidth = 60;
57 private int fHeight = 18;
59 private Object[] fSelection = new Object[0];
62 * Constructs a list selection dialog.
65 * The label renderer used
67 * Decides if the match string ignores lower/upppr case
68 * @param multipleSelection
69 * Allow multiple selection
71 protected AbstractElementListSelectionDialog(Shell parent,
72 ILabelProvider renderer) {
76 int shellStyle = getShellStyle();
77 setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
81 * Handles default selection (double click). By default, the OK button is
84 protected void handleDefaultSelected() {
85 if (validateCurrentSelection())
86 buttonPressed(IDialogConstants.OK_ID);
90 * Specifies if sorting, filtering and folding is case sensitive.
92 public void setIgnoreCase(boolean ignoreCase) {
93 fIgnoreCase = ignoreCase;
97 * Returns if sorting, filtering and folding is case sensitive.
99 public boolean isCaseIgnored() {
104 * Specifies whether everything or nothing should be filtered on empty
107 public void setMatchEmptyString(boolean matchEmptyString) {
108 fMatchEmptyString = matchEmptyString;
112 * Specifies if multiple selection is allowed.
114 public void setMultipleSelection(boolean multipleSelection) {
115 fIsMultipleSelection = multipleSelection;
119 * Specifies whether duplicate entries are displayed or not.
121 public void setAllowDuplicates(boolean allowDuplicates) {
122 fAllowDuplicates = allowDuplicates;
126 * Sets the list size in unit of characters.
129 * the width of the list.
131 * the height of the list.
133 public void setSize(int width, int height) {
139 * Sets the message to be displayed if the list is empty.
142 * the message to be displayed.
144 public void setEmptyListMessage(String message) {
145 fEmptyListMessage = message;
149 * Sets the message to be displayed if the selection is empty.
152 * the message to be displayed.
154 public void setEmptySelectionMessage(String message) {
155 fEmptySelectionMessage = message;
159 * Sets an optional validator to check if the selection is valid. The
160 * validator is invoked whenever the selection changes.
163 * the validator to validate the selection.
165 public void setValidator(ISelectionValidator validator) {
166 fValidator = validator;
170 * Sets the elements of the list (widget). To be called within open().
173 * the elements of the list.
175 protected void setListElements(Object[] elements) {
176 Assert.isNotNull(fFilteredList);
177 fFilteredList.setElements(elements);
181 * Sets the filter pattern.
184 * the filter pattern.
186 public void setFilter(String filter) {
187 if (fFilterText == null)
190 fFilterText.setText(filter);
194 * Returns the current filter pattern.
196 * @return returns the current filter pattern or
197 * <code>null<code> if filter was not set.
199 public String getFilter() {
200 if (fFilteredList == null)
203 return fFilteredList.getFilter();
207 * Returns the indices referring the current selection. To be called within
210 * @return returns the indices of the current selection.
212 protected int[] getSelectionIndices() {
213 Assert.isNotNull(fFilteredList);
214 return fFilteredList.getSelectionIndices();
218 * Returns an index referring the first current selection. To be called
221 * @return returns the indices of the current selection.
223 protected int getSelectionIndex() {
224 Assert.isNotNull(fFilteredList);
225 return fFilteredList.getSelectionIndex();
229 * Sets the selection referenced by an array of elements. To be called
233 * the indices of the selection.
235 protected void setSelection(Object[] selection) {
236 Assert.isNotNull(fFilteredList);
237 fFilteredList.setSelection(selection);
241 * Returns an array of the currently selected elements. To be called within
244 * @return returns an array of the currently selected elements.
246 protected Object[] getSelectedElements() {
247 Assert.isNotNull(fFilteredList);
248 return fFilteredList.getSelection();
252 * Returns all elements which are folded together to one entry in the list.
255 * the index selecting the entry in the list.
256 * @return returns an array of elements folded together.
258 public Object[] getFoldedElements(int index) {
259 Assert.isNotNull(fFilteredList);
260 return fFilteredList.getFoldedElements(index);
264 * Creates the message text widget and sets layout data.
267 * the parent composite of the message area.
269 protected Label createMessageArea(Composite composite) {
270 Label label = super.createMessageArea(composite);
272 GridData data = new GridData();
273 data.grabExcessVerticalSpace = false;
274 data.grabExcessHorizontalSpace = true;
275 data.horizontalAlignment = GridData.FILL;
276 data.verticalAlignment = GridData.BEGINNING;
277 label.setLayoutData(data);
285 * Handles a selection changed event. By default, the current selection is
288 protected void handleSelectionChanged() {
289 validateCurrentSelection();
293 * Validates the current selection and updates the status line accordingly.
295 protected boolean validateCurrentSelection() {
296 Assert.isNotNull(fFilteredList);
299 Object[] elements = getSelectedElements();
301 if (elements.length > 0) {
302 if (fValidator != null) {
303 status = fValidator.validate(elements);
305 status = new StatusInfo();
308 if (fFilteredList.isEmpty()) {
309 status = new StatusInfo(IStatus.ERROR, fEmptyListMessage);
311 status = new StatusInfo(IStatus.ERROR, fEmptySelectionMessage);
315 updateStatus(status);
317 return status.isOK();
321 * @see Dialog#cancelPressed
323 protected void cancelPressed() {
325 super.cancelPressed();
329 * Creates a filtered list.
332 * the parent composite.
333 * @return returns the filtered list widget.
335 protected FilteredList createFilteredList(Composite parent) {
336 int flags = SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL
337 | (fIsMultipleSelection ? SWT.MULTI : SWT.SINGLE);
339 FilteredList list = new FilteredList(parent, flags, fRenderer,
340 fIgnoreCase, fAllowDuplicates, fMatchEmptyString);
342 GridData data = new GridData();
343 data.widthHint = convertWidthInCharsToPixels(fWidth);
344 data.heightHint = convertHeightInCharsToPixels(fHeight);
345 data.grabExcessVerticalSpace = true;
346 data.grabExcessHorizontalSpace = true;
347 data.horizontalAlignment = GridData.FILL;
348 data.verticalAlignment = GridData.FILL;
349 list.setLayoutData(data);
351 list.setFilter((fFilter == null ? "" : fFilter)); //$NON-NLS-1$
353 list.addSelectionListener(new SelectionListener() {
354 public void widgetDefaultSelected(SelectionEvent e) {
355 handleDefaultSelected();
358 public void widgetSelected(SelectionEvent e) {
359 handleWidgetSelected();
363 fFilteredList = list;
369 private void handleWidgetSelected() {
370 Object[] newSelection = fFilteredList.getSelection();
372 if (newSelection.length != fSelection.length) {
373 fSelection = newSelection;
374 handleSelectionChanged();
376 for (int i = 0; i != newSelection.length; i++) {
377 if (!newSelection[i].equals(fSelection[i])) {
378 fSelection = newSelection;
379 handleSelectionChanged();
386 protected Text createFilterText(Composite parent) {
387 Text text = new Text(parent, SWT.BORDER);
389 GridData data = new GridData();
390 data.grabExcessVerticalSpace = false;
391 data.grabExcessHorizontalSpace = true;
392 data.horizontalAlignment = GridData.FILL;
393 data.verticalAlignment = GridData.BEGINNING;
394 text.setLayoutData(data);
396 text.setText((fFilter == null ? "" : fFilter)); //$NON-NLS-1$
398 Listener listener = new Listener() {
399 public void handleEvent(Event e) {
400 fFilteredList.setFilter(fFilterText.getText());
403 text.addListener(SWT.Modify, listener);
405 text.addKeyListener(new KeyListener() {
406 public void keyPressed(KeyEvent e) {
407 if (e.keyCode == SWT.ARROW_DOWN)
408 fFilteredList.setFocus();
411 public void keyReleased(KeyEvent e) {
424 BusyIndicator.showWhile(null, new Runnable() {
429 return getReturnCode();
432 private void access$superOpen() {
437 * @see Window#create(Shell)
439 public void create() {
442 Assert.isNotNull(fFilteredList);
444 if (fFilteredList.isEmpty()) {
447 validateCurrentSelection();
448 fFilterText.selectAll();
449 fFilterText.setFocus();
454 * Handles empty list by disabling widgets.
456 protected void handleEmptyList() {
457 fMessage.setEnabled(false);
458 fFilterText.setEnabled(false);
459 fFilteredList.setEnabled(false);