1 /*******************************************************************************
 
   2  * Copyright (c) 2000, 2004 IBM Corporation and others.
 
   3  * All rights reserved. This program and the accompanying materials
 
   4  * are made available under the terms of the Common Public License v1.0
 
   5  * which accompanies this distribution, and is available at
 
   6  * http://www.eclipse.org/legal/cpl-v10.html
 
   9  *     IBM Corporation - initial API and implementation
 
  10  *******************************************************************************/
 
  11 package net.sourceforge.phpdt.internal.ui.filters;
 
  13 import java.util.ArrayList;
 
  14 import java.util.Arrays;
 
  15 import java.util.HashSet;
 
  16 import java.util.Iterator;
 
  17 import java.util.List;
 
  19 import java.util.Stack;
 
  20 import java.util.StringTokenizer;
 
  22 import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
 
  23 import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
 
  25 import org.eclipse.jface.dialogs.IDialogConstants;
 
  26 import org.eclipse.jface.util.Assert;
 
  27 import org.eclipse.jface.viewers.ArrayContentProvider;
 
  28 import org.eclipse.jface.viewers.CheckStateChangedEvent;
 
  29 import org.eclipse.jface.viewers.CheckboxTableViewer;
 
  30 import org.eclipse.jface.viewers.ICheckStateListener;
 
  31 import org.eclipse.jface.viewers.ILabelProvider;
 
  32 import org.eclipse.jface.viewers.ISelection;
 
  33 import org.eclipse.jface.viewers.ISelectionChangedListener;
 
  34 import org.eclipse.jface.viewers.IStructuredSelection;
 
  35 import org.eclipse.jface.viewers.LabelProvider;
 
  36 import org.eclipse.jface.viewers.SelectionChangedEvent;
 
  37 import org.eclipse.swt.SWT;
 
  38 import org.eclipse.swt.events.SelectionAdapter;
 
  39 import org.eclipse.swt.events.SelectionEvent;
 
  40 import org.eclipse.swt.events.SelectionListener;
 
  41 import org.eclipse.swt.graphics.Image;
 
  42 import org.eclipse.swt.layout.GridData;
 
  43 import org.eclipse.swt.layout.GridLayout;
 
  44 import org.eclipse.swt.widgets.Button;
 
  45 import org.eclipse.swt.widgets.Composite;
 
  46 import org.eclipse.swt.widgets.Control;
 
  47 import org.eclipse.swt.widgets.Label;
 
  48 import org.eclipse.swt.widgets.Shell;
 
  49 import org.eclipse.swt.widgets.Text;
 
  50 import org.eclipse.ui.PlatformUI;
 
  51 import org.eclipse.ui.dialogs.SelectionDialog;
 
  53 public class CustomFiltersDialog extends SelectionDialog {
 
  55         private static final String SEPARATOR = ","; //$NON-NLS-1$
 
  57         private String fViewId;
 
  59         private boolean fEnablePatterns;
 
  61         private String[] fPatterns;
 
  63         private String[] fEnabledFilterIds;
 
  65         private FilterDescriptor[] fBuiltInFilters;
 
  67         private CheckboxTableViewer fCheckBoxList;
 
  69         private Button fEnableUserDefinedPatterns;
 
  71         private Text fUserDefinedPatterns;
 
  73         private Stack fFilterDescriptorChangeHistory;
 
  76          * Creates a dialog to customize Java element filters.
 
  82          * @param enablePatterns
 
  83          *            <code>true</code> if pattern filters are enabled
 
  86          * @param enabledFilterIds
 
  87          *            the Ids of the enabled filters
 
  89         public CustomFiltersDialog(Shell shell, String viewId,
 
  90                         boolean enablePatterns, String[] patterns, String[] enabledFilterIds) {
 
  93                 Assert.isNotNull(viewId);
 
  94                 Assert.isNotNull(patterns);
 
  95                 Assert.isNotNull(enabledFilterIds);
 
  99                 fEnablePatterns = enablePatterns;
 
 100                 fEnabledFilterIds = enabledFilterIds;
 
 102                 fBuiltInFilters = FilterDescriptor.getFilterDescriptors(fViewId);
 
 103                 fFilterDescriptorChangeHistory = new Stack();
 
 104                 setShellStyle(getShellStyle() | SWT.RESIZE);
 
 107         protected void configureShell(Shell shell) {
 
 108                 setTitle(FilterMessages.getString("CustomFiltersDialog.title")); //$NON-NLS-1$
 
 109                 setMessage(FilterMessages
 
 110                                 .getString("CustomFiltersDialog.filterList.label")); //$NON-NLS-1$
 
 111                 super.configureShell(shell);
 
 112                 PlatformUI.getWorkbench().getHelpSystem().setHelp(shell,
 
 113                                 IJavaHelpContextIds.CUSTOM_FILTERS_DIALOG);
 
 117          * Overrides method in Dialog
 
 119          * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite)
 
 121         protected Control createDialogArea(Composite parent) {
 
 122                 initializeDialogUnits(parent);
 
 123                 // create a composite with standard margins and spacing
 
 124                 Composite composite = new Composite(parent, SWT.NONE);
 
 125                 GridLayout layout = new GridLayout();
 
 126                 layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
 
 127                 layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
 
 128                 layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
 
 129                 layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
 
 130                 composite.setLayout(layout);
 
 131                 composite.setLayoutData(new GridData(GridData.FILL_BOTH));
 
 132                 composite.setFont(parent.getFont());
 
 133                 Composite group = composite;
 
 136                 fEnableUserDefinedPatterns = new Button(group, SWT.CHECK);
 
 137                 fEnableUserDefinedPatterns.setFocus();
 
 138                 fEnableUserDefinedPatterns.setText(FilterMessages
 
 139                                 .getString("CustomFiltersDialog.enableUserDefinedPattern")); //$NON-NLS-1$
 
 142                 fUserDefinedPatterns = new Text(group, SWT.SINGLE | SWT.BORDER);
 
 143                 GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
 
 144                                 | GridData.GRAB_HORIZONTAL);
 
 145                 data.widthHint = convertWidthInCharsToPixels(59);
 
 146                 fUserDefinedPatterns.setLayoutData(data);
 
 147                 String patterns = convertToString(fPatterns, SEPARATOR);
 
 148                 fUserDefinedPatterns.setText(patterns);
 
 151                 final Label info = new Label(group, SWT.LEFT);
 
 152                 info.setText(FilterMessages
 
 153                                 .getString("CustomFiltersDialog.patternInfo")); //$NON-NLS-1$
 
 155                 // Enabling / disabling of pattern group
 
 156                 fEnableUserDefinedPatterns.setSelection(fEnablePatterns);
 
 157                 fUserDefinedPatterns.setEnabled(fEnablePatterns);
 
 158                 info.setEnabled(fEnablePatterns);
 
 159                 fEnableUserDefinedPatterns.addSelectionListener(new SelectionAdapter() {
 
 160                         public void widgetSelected(SelectionEvent e) {
 
 161                                 boolean state = fEnableUserDefinedPatterns.getSelection();
 
 162                                 fUserDefinedPatterns.setEnabled(state);
 
 163                                 info.setEnabled(fEnableUserDefinedPatterns.getSelection());
 
 165                                         fUserDefinedPatterns.setFocus();
 
 169                 // Filters provided by extension point
 
 170                 if (fBuiltInFilters.length > 0)
 
 171                         createCheckBoxList(group);
 
 173                 applyDialogFont(parent);
 
 177         private void createCheckBoxList(Composite parent) {
 
 179                 new Label(parent, SWT.NONE);
 
 181                 Label info = new Label(parent, SWT.LEFT);
 
 182                 info.setText(FilterMessages
 
 183                                 .getString("CustomFiltersDialog.filterList.label")); //$NON-NLS-1$
 
 185                 fCheckBoxList = CheckboxTableViewer.newCheckList(parent, SWT.BORDER);
 
 186                 GridData data = new GridData(GridData.FILL_BOTH);
 
 187                 data.heightHint = fCheckBoxList.getTable().getItemHeight() * 10;
 
 188                 fCheckBoxList.getTable().setLayoutData(data);
 
 190                 fCheckBoxList.setLabelProvider(createLabelPrivder());
 
 191                 fCheckBoxList.setContentProvider(new ArrayContentProvider());
 
 193                 fCheckBoxList.setInput(fBuiltInFilters);
 
 194                 setInitialSelections(getEnabledFilterDescriptors());
 
 196                 List initialSelection = getInitialElementSelections();
 
 197                 if (initialSelection != null && !initialSelection.isEmpty())
 
 198                         checkInitialSelections();
 
 201                 info = new Label(parent, SWT.LEFT);
 
 202                 info.setText(FilterMessages
 
 203                                 .getString("CustomFiltersDialog.description.label")); //$NON-NLS-1$
 
 204                 final Text description = new Text(parent, SWT.LEFT | SWT.WRAP
 
 205                                 | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.V_SCROLL);
 
 206                 data = new GridData(GridData.FILL_HORIZONTAL);
 
 207                 data.heightHint = convertHeightInCharsToPixels(3);
 
 208                 description.setLayoutData(data);
 
 210                                 .addSelectionChangedListener(new ISelectionChangedListener() {
 
 211                                         public void selectionChanged(SelectionChangedEvent event) {
 
 212                                                 ISelection selection = event.getSelection();
 
 213                                                 if (selection instanceof IStructuredSelection) {
 
 214                                                         Object selectedElement = ((IStructuredSelection) selection)
 
 216                                                         if (selectedElement instanceof FilterDescriptor)
 
 218                                                                                 .setText(((FilterDescriptor) selectedElement)
 
 223                 fCheckBoxList.addCheckStateListener(new ICheckStateListener() {
 
 225                          * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
 
 227                         public void checkStateChanged(CheckStateChangedEvent event) {
 
 228                                 Object element = event.getElement();
 
 229                                 if (element instanceof FilterDescriptor) {
 
 230                                         // renew if already touched
 
 231                                         if (fFilterDescriptorChangeHistory.contains(element))
 
 232                                                 fFilterDescriptorChangeHistory.remove(element);
 
 233                                         fFilterDescriptorChangeHistory.push(element);
 
 238                 addSelectionButtons(parent);
 
 241         private void addSelectionButtons(Composite composite) {
 
 242                 Composite buttonComposite = new Composite(composite, SWT.RIGHT);
 
 243                 GridLayout layout = new GridLayout();
 
 244                 layout.numColumns = 2;
 
 245                 buttonComposite.setLayout(layout);
 
 246                 GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END
 
 247                                 | GridData.GRAB_HORIZONTAL);
 
 248                 data.grabExcessHorizontalSpace = true;
 
 249                 composite.setData(data);
 
 252                 String label = FilterMessages
 
 253                                 .getString("CustomFiltersDialog.SelectAllButton.label"); //$NON-NLS-1$
 
 254                 Button selectButton = createButton(buttonComposite,
 
 255                                 IDialogConstants.SELECT_ALL_ID, label, false);
 
 256                 SWTUtil.setButtonDimensionHint(selectButton);
 
 257                 SelectionListener listener = new SelectionAdapter() {
 
 258                         public void widgetSelected(SelectionEvent e) {
 
 259                                 fCheckBoxList.setAllChecked(true);
 
 260                                 fFilterDescriptorChangeHistory.clear();
 
 261                                 for (int i = 0; i < fBuiltInFilters.length; i++)
 
 262                                         fFilterDescriptorChangeHistory.push(fBuiltInFilters[i]);
 
 265                 selectButton.addSelectionListener(listener);
 
 267                 // De-select All button
 
 268                 label = FilterMessages
 
 269                                 .getString("CustomFiltersDialog.DeselectAllButton.label"); //$NON-NLS-1$
 
 270                 Button deselectButton = createButton(buttonComposite,
 
 271                                 IDialogConstants.DESELECT_ALL_ID, label, false);
 
 272                 SWTUtil.setButtonDimensionHint(deselectButton);
 
 273                 listener = new SelectionAdapter() {
 
 274                         public void widgetSelected(SelectionEvent e) {
 
 275                                 fCheckBoxList.setAllChecked(false);
 
 276                                 fFilterDescriptorChangeHistory.clear();
 
 277                                 for (int i = 0; i < fBuiltInFilters.length; i++)
 
 278                                         fFilterDescriptorChangeHistory.push(fBuiltInFilters[i]);
 
 281                 deselectButton.addSelectionListener(listener);
 
 284         private void checkInitialSelections() {
 
 285                 Iterator itemsToCheck = getInitialElementSelections().iterator();
 
 286                 while (itemsToCheck.hasNext())
 
 287                         fCheckBoxList.setChecked(itemsToCheck.next(), true);
 
 290         protected void okPressed() {
 
 291                 if (fBuiltInFilters != null) {
 
 292                         ArrayList result = new ArrayList();
 
 293                         for (int i = 0; i < fBuiltInFilters.length; ++i) {
 
 294                                 if (fCheckBoxList.getChecked(fBuiltInFilters[i]))
 
 295                                         result.add(fBuiltInFilters[i]);
 
 302         private ILabelProvider createLabelPrivder() {
 
 303                 return new LabelProvider() {
 
 304                         public Image getImage(Object element) {
 
 308                         public String getText(Object element) {
 
 309                                 if (element instanceof FilterDescriptor)
 
 310                                         return ((FilterDescriptor) element).getName();
 
 317         // ---------- result handling ----------
 
 319         protected void setResult(List newResult) {
 
 320                 super.setResult(newResult);
 
 321                 if (fUserDefinedPatterns.getText().length() > 0) {
 
 322                         fEnablePatterns = fEnableUserDefinedPatterns.getSelection();
 
 323                         fPatterns = convertFromString(fUserDefinedPatterns.getText(),
 
 326                         fEnablePatterns = false;
 
 327                         fPatterns = new String[0];
 
 332          * @return the patterns which have been entered by the user
 
 334         public String[] getUserDefinedPatterns() {
 
 339          * @return the Ids of the enabled built-in filters
 
 341         public String[] getEnabledFilterIds() {
 
 342                 Object[] result = getResult();
 
 343                 Set enabledIds = new HashSet(result.length);
 
 344                 for (int i = 0; i < result.length; i++)
 
 345                         enabledIds.add(((FilterDescriptor) result[i]).getId());
 
 346                 return (String[]) enabledIds.toArray(new String[enabledIds.size()]);
 
 350          * @return <code>true</code> if the user-defined patterns are disabled
 
 352         public boolean areUserDefinedPatternsEnabled() {
 
 353                 return fEnablePatterns;
 
 357          * @return a stack with the filter descriptor check history
 
 360         public Stack getFilterDescriptorChangeHistory() {
 
 361                 return fFilterDescriptorChangeHistory;
 
 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]);
 
 373                 return (FilterDescriptor[]) result.toArray(new FilterDescriptor[result
 
 377         public static String[] convertFromString(String patterns, String separator) {
 
 378                 StringTokenizer tokenizer = new StringTokenizer(patterns, separator,
 
 380                 int tokenCount = tokenizer.countTokens();
 
 381                 List result = new ArrayList(tokenCount);
 
 382                 boolean escape = false;
 
 383                 boolean append = false;
 
 384                 while (tokenizer.hasMoreTokens()) {
 
 385                         String token = tokenizer.nextToken().trim();
 
 386                         if (separator.equals(token)) {
 
 390                                         addPattern(result, separator);
 
 397                                         addPattern(result, token);
 
 402                 return (String[]) result.toArray(new String[result.size()]);
 
 405         private static void addPattern(List list, String pattern) {
 
 409                         int index = list.size() - 1;
 
 410                         list.set(index, ((String) list.get(index)) + pattern);
 
 414         public static String convertToString(String[] patterns, String separator) {
 
 415                 int length = patterns.length;
 
 416                 StringBuffer strBuf = new StringBuffer();
 
 418                         strBuf.append(escapeSeparator(patterns[0], separator));
 
 420                         return ""; //$NON-NLS-1$
 
 423                         strBuf.append(separator);
 
 424                         strBuf.append(" "); //$NON-NLS-1$
 
 425                         strBuf.append(escapeSeparator(patterns[i++], separator));
 
 427                 return strBuf.toString();
 
 430         private static String escapeSeparator(String pattern, String separator) {
 
 431                 int length = pattern.length();
 
 432                 StringBuffer buf = new StringBuffer(length);
 
 433                 for (int i = 0; i < length; i++) {
 
 434                         char ch = pattern.charAt(i); //$NON-NLS-1$
 
 435                         if (separator.equals(String.valueOf(ch)))
 
 439                 return buf.toString();