001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.filters;
011:
012: import java.util.ArrayList;
013: import java.util.Arrays;
014: import java.util.HashSet;
015: import java.util.Iterator;
016: import java.util.List;
017: import java.util.Set;
018: import java.util.Stack;
019: import java.util.StringTokenizer;
020:
021: import org.eclipse.core.runtime.Assert;
022:
023: import org.eclipse.swt.SWT;
024: import org.eclipse.swt.events.SelectionAdapter;
025: import org.eclipse.swt.events.SelectionEvent;
026: import org.eclipse.swt.events.SelectionListener;
027: import org.eclipse.swt.graphics.Image;
028: import org.eclipse.swt.layout.GridData;
029: import org.eclipse.swt.layout.GridLayout;
030: import org.eclipse.swt.widgets.Button;
031: import org.eclipse.swt.widgets.Composite;
032: import org.eclipse.swt.widgets.Control;
033: import org.eclipse.swt.widgets.Label;
034: import org.eclipse.swt.widgets.Shell;
035: import org.eclipse.swt.widgets.Text;
036:
037: import org.eclipse.jface.dialogs.IDialogConstants;
038: import org.eclipse.jface.viewers.ArrayContentProvider;
039: import org.eclipse.jface.viewers.CheckStateChangedEvent;
040: import org.eclipse.jface.viewers.CheckboxTableViewer;
041: import org.eclipse.jface.viewers.ICheckStateListener;
042: import org.eclipse.jface.viewers.ILabelProvider;
043: import org.eclipse.jface.viewers.ISelection;
044: import org.eclipse.jface.viewers.ISelectionChangedListener;
045: import org.eclipse.jface.viewers.IStructuredSelection;
046: import org.eclipse.jface.viewers.LabelProvider;
047: import org.eclipse.jface.viewers.SelectionChangedEvent;
048:
049: import org.eclipse.ui.PlatformUI;
050: import org.eclipse.ui.dialogs.SelectionDialog;
051:
052: import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
053: import org.eclipse.jdt.internal.ui.util.SWTUtil;
054:
055: public class CustomFiltersDialog extends SelectionDialog {
056:
057: private static final String SEPARATOR = ","; //$NON-NLS-1$
058:
059: private String fViewId;
060: private boolean fEnablePatterns;
061: private String[] fPatterns;
062: private String[] fEnabledFilterIds;
063:
064: private FilterDescriptor[] fBuiltInFilters;
065:
066: private CheckboxTableViewer fCheckBoxList;
067: private Button fEnableUserDefinedPatterns;
068: private Text fUserDefinedPatterns;
069:
070: private Stack fFilterDescriptorChangeHistory;
071:
072: /**
073: * Creates a dialog to customize Java element filters.
074: *
075: * @param shell the parent shell
076: * @param viewId the id of the view
077: * @param enablePatterns <code>true</code> if pattern filters are enabled
078: * @param patterns the filter patterns
079: * @param enabledFilterIds the Ids of the enabled filters
080: */
081: public CustomFiltersDialog(Shell shell, String viewId,
082: boolean enablePatterns, String[] patterns,
083: String[] enabledFilterIds) {
084:
085: super (shell);
086: Assert.isNotNull(viewId);
087: Assert.isNotNull(patterns);
088: Assert.isNotNull(enabledFilterIds);
089:
090: fViewId = viewId;
091: fPatterns = patterns;
092: fEnablePatterns = enablePatterns;
093: fEnabledFilterIds = enabledFilterIds;
094:
095: fBuiltInFilters = FilterDescriptor
096: .getFilterDescriptors(fViewId);
097: fFilterDescriptorChangeHistory = new Stack();
098: setShellStyle(getShellStyle() | SWT.RESIZE);
099: }
100:
101: protected void configureShell(Shell shell) {
102: setTitle(FilterMessages.CustomFiltersDialog_title);
103: setMessage(FilterMessages.CustomFiltersDialog_filterList_label);
104: super .configureShell(shell);
105: PlatformUI.getWorkbench().getHelpSystem().setHelp(shell,
106: IJavaHelpContextIds.CUSTOM_FILTERS_DIALOG);
107: }
108:
109: /**
110: * Overrides method in Dialog
111: *
112: * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite)
113: */
114: protected Control createDialogArea(Composite parent) {
115: initializeDialogUnits(parent);
116: // create a composite with standard margins and spacing
117: Composite composite = new Composite(parent, SWT.NONE);
118: GridLayout layout = new GridLayout();
119: layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
120: layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
121: layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
122: layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
123: composite.setLayout(layout);
124: composite.setLayoutData(new GridData(GridData.FILL_BOTH));
125: composite.setFont(parent.getFont());
126: Composite group = composite;
127:
128: // Checkbox
129: fEnableUserDefinedPatterns = new Button(group, SWT.CHECK);
130: fEnableUserDefinedPatterns.setFocus();
131: fEnableUserDefinedPatterns
132: .setText(FilterMessages.CustomFiltersDialog_enableUserDefinedPattern);
133:
134: // Pattern field
135: fUserDefinedPatterns = new Text(group, SWT.SINGLE | SWT.BORDER);
136: GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
137: | GridData.GRAB_HORIZONTAL);
138: data.widthHint = convertWidthInCharsToPixels(59);
139: fUserDefinedPatterns.setLayoutData(data);
140: String patterns = convertToString(fPatterns, SEPARATOR);
141: fUserDefinedPatterns.setText(patterns);
142:
143: // Info text
144: final Label info = new Label(group, SWT.LEFT);
145: info.setText(FilterMessages.CustomFiltersDialog_patternInfo);
146:
147: // Enabling / disabling of pattern group
148: fEnableUserDefinedPatterns.setSelection(fEnablePatterns);
149: fUserDefinedPatterns.setEnabled(fEnablePatterns);
150: info.setEnabled(fEnablePatterns);
151: fEnableUserDefinedPatterns
152: .addSelectionListener(new SelectionAdapter() {
153: public void widgetSelected(SelectionEvent e) {
154: boolean state = fEnableUserDefinedPatterns
155: .getSelection();
156: fUserDefinedPatterns.setEnabled(state);
157: info.setEnabled(fEnableUserDefinedPatterns
158: .getSelection());
159: if (state)
160: fUserDefinedPatterns.setFocus();
161: }
162: });
163:
164: // Filters provided by extension point
165: if (fBuiltInFilters.length > 0)
166: createCheckBoxList(group);
167:
168: applyDialogFont(parent);
169: return parent;
170: }
171:
172: private void createCheckBoxList(Composite parent) {
173: // Filler
174: new Label(parent, SWT.NONE);
175:
176: Label info = new Label(parent, SWT.LEFT);
177: info
178: .setText(FilterMessages.CustomFiltersDialog_filterList_label);
179:
180: fCheckBoxList = CheckboxTableViewer.newCheckList(parent,
181: SWT.BORDER);
182: GridData data = new GridData(GridData.FILL_BOTH);
183: data.heightHint = fCheckBoxList.getTable().getItemHeight() * 10;
184: fCheckBoxList.getTable().setLayoutData(data);
185:
186: fCheckBoxList.setLabelProvider(createLabelPrivder());
187: fCheckBoxList.setContentProvider(new ArrayContentProvider());
188: Arrays.sort(fBuiltInFilters);
189: fCheckBoxList.setInput(fBuiltInFilters);
190: setInitialSelections(getEnabledFilterDescriptors());
191:
192: List initialSelection = getInitialElementSelections();
193: if (initialSelection != null && !initialSelection.isEmpty())
194: checkInitialSelections();
195:
196: // Description
197: info = new Label(parent, SWT.LEFT);
198: info
199: .setText(FilterMessages.CustomFiltersDialog_description_label);
200: final Text description = new Text(parent, SWT.LEFT | SWT.WRAP
201: | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.V_SCROLL);
202: data = new GridData(GridData.FILL_HORIZONTAL);
203: data.heightHint = convertHeightInCharsToPixels(3);
204: description.setLayoutData(data);
205: fCheckBoxList
206: .addSelectionChangedListener(new ISelectionChangedListener() {
207: public void selectionChanged(
208: SelectionChangedEvent event) {
209: ISelection selection = event.getSelection();
210: if (selection instanceof IStructuredSelection) {
211: Object selectedElement = ((IStructuredSelection) selection)
212: .getFirstElement();
213: if (selectedElement instanceof FilterDescriptor)
214: description
215: .setText(((FilterDescriptor) selectedElement)
216: .getDescription());
217: }
218: }
219: });
220: fCheckBoxList.addCheckStateListener(new ICheckStateListener() {
221: /*
222: * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
223: */
224: public void checkStateChanged(CheckStateChangedEvent event) {
225: Object element = event.getElement();
226: if (element instanceof FilterDescriptor) {
227: // renew if already touched
228: if (fFilterDescriptorChangeHistory
229: .contains(element))
230: fFilterDescriptorChangeHistory.remove(element);
231: fFilterDescriptorChangeHistory.push(element);
232: }
233: }
234: });
235:
236: addSelectionButtons(parent);
237: }
238:
239: private void addSelectionButtons(Composite composite) {
240: Composite buttonComposite = new Composite(composite, SWT.RIGHT);
241: GridLayout layout = new GridLayout();
242: layout.numColumns = 2;
243: buttonComposite.setLayout(layout);
244: GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END
245: | GridData.GRAB_HORIZONTAL);
246: data.grabExcessHorizontalSpace = true;
247: composite.setData(data);
248:
249: // Select All button
250: String label = FilterMessages.CustomFiltersDialog_SelectAllButton_label;
251: Button selectButton = createButton(buttonComposite,
252: IDialogConstants.SELECT_ALL_ID, label, false);
253: SWTUtil.setButtonDimensionHint(selectButton);
254: SelectionListener listener = new SelectionAdapter() {
255: public void widgetSelected(SelectionEvent e) {
256: fCheckBoxList.setAllChecked(true);
257: fFilterDescriptorChangeHistory.clear();
258: for (int i = 0; i < fBuiltInFilters.length; i++)
259: fFilterDescriptorChangeHistory
260: .push(fBuiltInFilters[i]);
261: }
262: };
263: selectButton.addSelectionListener(listener);
264:
265: // De-select All button
266: label = FilterMessages.CustomFiltersDialog_DeselectAllButton_label;
267: Button deselectButton = createButton(buttonComposite,
268: IDialogConstants.DESELECT_ALL_ID, label, false);
269: SWTUtil.setButtonDimensionHint(deselectButton);
270: listener = new SelectionAdapter() {
271: public void widgetSelected(SelectionEvent e) {
272: fCheckBoxList.setAllChecked(false);
273: fFilterDescriptorChangeHistory.clear();
274: for (int i = 0; i < fBuiltInFilters.length; i++)
275: fFilterDescriptorChangeHistory
276: .push(fBuiltInFilters[i]);
277: }
278: };
279: deselectButton.addSelectionListener(listener);
280: }
281:
282: private void checkInitialSelections() {
283: Iterator itemsToCheck = getInitialElementSelections()
284: .iterator();
285: while (itemsToCheck.hasNext())
286: fCheckBoxList.setChecked(itemsToCheck.next(), true);
287: }
288:
289: protected void okPressed() {
290: if (fBuiltInFilters != null) {
291: ArrayList result = new ArrayList();
292: for (int i = 0; i < fBuiltInFilters.length; ++i) {
293: if (fCheckBoxList.getChecked(fBuiltInFilters[i]))
294: result.add(fBuiltInFilters[i]);
295: }
296: setResult(result);
297: }
298: super .okPressed();
299: }
300:
301: private ILabelProvider createLabelPrivder() {
302: return new LabelProvider() {
303: public Image getImage(Object element) {
304: return null;
305: }
306:
307: public String getText(Object element) {
308: if (element instanceof FilterDescriptor)
309: return ((FilterDescriptor) element).getName();
310: else
311: return null;
312: }
313: };
314: }
315:
316: // ---------- result handling ----------
317:
318: protected void setResult(List newResult) {
319: super .setResult(newResult);
320: if (fUserDefinedPatterns.getText().length() > 0) {
321: fEnablePatterns = fEnableUserDefinedPatterns.getSelection();
322: fPatterns = convertFromString(fUserDefinedPatterns
323: .getText(), SEPARATOR);
324: } else {
325: fEnablePatterns = false;
326: fPatterns = new String[0];
327: }
328: }
329:
330: /**
331: * @return the patterns which have been entered by the user
332: */
333: public String[] getUserDefinedPatterns() {
334: return fPatterns;
335: }
336:
337: /**
338: * @return the Ids of the enabled built-in filters
339: */
340: public String[] getEnabledFilterIds() {
341: Object[] result = getResult();
342: Set enabledIds = new HashSet(result.length);
343: for (int i = 0; i < result.length; i++)
344: enabledIds.add(((FilterDescriptor) result[i]).getId());
345: return (String[]) enabledIds.toArray(new String[enabledIds
346: .size()]);
347: }
348:
349: /**
350: * @return <code>true</code> if the user-defined patterns are disabled
351: */
352: public boolean areUserDefinedPatternsEnabled() {
353: return fEnablePatterns;
354: }
355:
356: /**
357: * @return a stack with the filter descriptor check history
358: * @since 3.0
359: */
360: public Stack getFilterDescriptorChangeHistory() {
361: return fFilterDescriptorChangeHistory;
362: }
363:
364: private FilterDescriptor[] getEnabledFilterDescriptors() {
365: FilterDescriptor[] filterDescs = fBuiltInFilters;
366: List result = new ArrayList(filterDescs.length);
367: List enabledFilterIds = Arrays.asList(fEnabledFilterIds);
368: for (int i = 0; i < filterDescs.length; i++) {
369: String id = filterDescs[i].getId();
370: if (enabledFilterIds.contains(id))
371: result.add(filterDescs[i]);
372: }
373: return (FilterDescriptor[]) result
374: .toArray(new FilterDescriptor[result.size()]);
375: }
376:
377: public static String[] convertFromString(String patterns,
378: String separator) {
379: StringTokenizer tokenizer = new StringTokenizer(patterns,
380: separator, true);
381: int tokenCount = tokenizer.countTokens();
382: List result = new ArrayList(tokenCount);
383: boolean escape = false;
384: boolean append = false;
385: while (tokenizer.hasMoreTokens()) {
386: String token = tokenizer.nextToken().trim();
387: if (separator.equals(token)) {
388: if (!escape)
389: escape = true;
390: else {
391: addPattern(result, separator);
392: append = true;
393: }
394: } else {
395: if (!append)
396: result.add(token);
397: else
398: addPattern(result, token);
399: append = false;
400: escape = false;
401: }
402: }
403: return (String[]) result.toArray(new String[result.size()]);
404: }
405:
406: private static void addPattern(List list, String pattern) {
407: if (list.isEmpty())
408: list.add(pattern);
409: else {
410: int index = list.size() - 1;
411: list.set(index, ((String) list.get(index)) + pattern);
412: }
413: }
414:
415: public static String convertToString(String[] patterns,
416: String separator) {
417: int length = patterns.length;
418: StringBuffer strBuf = new StringBuffer();
419: if (length > 0)
420: strBuf.append(escapeSeparator(patterns[0], separator));
421: else
422: return ""; //$NON-NLS-1$
423: int i = 1;
424: while (i < length) {
425: strBuf.append(separator);
426: strBuf.append(" "); //$NON-NLS-1$
427: strBuf.append(escapeSeparator(patterns[i++], separator));
428: }
429: return strBuf.toString();
430: }
431:
432: private static String escapeSeparator(String pattern,
433: String separator) {
434: int length = pattern.length();
435: StringBuffer buf = new StringBuffer(length);
436: for (int i = 0; i < length; i++) {
437: char ch = pattern.charAt(i);
438: if (separator.equals(String.valueOf(ch)))
439: buf.append(ch);
440: buf.append(ch);
441: }
442: return buf.toString();
443:
444: }
445: }
|