refactory: added UI removed from core plugin.
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / src / net / sourceforge / phpdt / internal / ui / filters / CustomFiltersDialog.java
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
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.filters;
12
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;
18 import java.util.Set;
19 import java.util.Stack;
20 import java.util.StringTokenizer;
21
22 import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
23 import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
24
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;
52
53 public class CustomFiltersDialog extends SelectionDialog {
54
55         private static final String SEPARATOR = ","; //$NON-NLS-1$
56
57         private String fViewId;
58
59         private boolean fEnablePatterns;
60
61         private String[] fPatterns;
62
63         private String[] fEnabledFilterIds;
64
65         private FilterDescriptor[] fBuiltInFilters;
66
67         private CheckboxTableViewer fCheckBoxList;
68
69         private Button fEnableUserDefinedPatterns;
70
71         private Text fUserDefinedPatterns;
72
73         private Stack fFilterDescriptorChangeHistory;
74
75         /**
76          * Creates a dialog to customize Java element filters.
77          * 
78          * @param shell
79          *            the parent shell
80          * @param viewId
81          *            the id of the view
82          * @param enablePatterns
83          *            <code>true</code> if pattern filters are enabled
84          * @param patterns
85          *            the filter patterns
86          * @param enabledFilterIds
87          *            the Ids of the enabled filters
88          */
89         public CustomFiltersDialog(Shell shell, String viewId,
90                         boolean enablePatterns, String[] patterns, String[] enabledFilterIds) {
91
92                 super(shell);
93                 Assert.isNotNull(viewId);
94                 Assert.isNotNull(patterns);
95                 Assert.isNotNull(enabledFilterIds);
96
97                 fViewId = viewId;
98                 fPatterns = patterns;
99                 fEnablePatterns = enablePatterns;
100                 fEnabledFilterIds = enabledFilterIds;
101
102                 fBuiltInFilters = FilterDescriptor.getFilterDescriptors(fViewId);
103                 fFilterDescriptorChangeHistory = new Stack();
104                 setShellStyle(getShellStyle() | SWT.RESIZE);
105         }
106
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);
114         }
115
116         /**
117          * Overrides method in Dialog
118          * 
119          * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite)
120          */
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;
134
135                 // Checkbox
136                 fEnableUserDefinedPatterns = new Button(group, SWT.CHECK);
137                 fEnableUserDefinedPatterns.setFocus();
138                 fEnableUserDefinedPatterns.setText(FilterMessages
139                                 .getString("CustomFiltersDialog.enableUserDefinedPattern")); //$NON-NLS-1$
140
141                 // Pattern field
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);
149
150                 // Info text
151                 final Label info = new Label(group, SWT.LEFT);
152                 info.setText(FilterMessages
153                                 .getString("CustomFiltersDialog.patternInfo")); //$NON-NLS-1$
154
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());
164                                 if (state)
165                                         fUserDefinedPatterns.setFocus();
166                         }
167                 });
168
169                 // Filters provided by extension point
170                 if (fBuiltInFilters.length > 0)
171                         createCheckBoxList(group);
172
173                 applyDialogFont(parent);
174                 return parent;
175         }
176
177         private void createCheckBoxList(Composite parent) {
178                 // Filler
179                 new Label(parent, SWT.NONE);
180
181                 Label info = new Label(parent, SWT.LEFT);
182                 info.setText(FilterMessages
183                                 .getString("CustomFiltersDialog.filterList.label")); //$NON-NLS-1$
184
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);
189
190                 fCheckBoxList.setLabelProvider(createLabelPrivder());
191                 fCheckBoxList.setContentProvider(new ArrayContentProvider());
192
193                 fCheckBoxList.setInput(fBuiltInFilters);
194                 setInitialSelections(getEnabledFilterDescriptors());
195
196                 List initialSelection = getInitialElementSelections();
197                 if (initialSelection != null && !initialSelection.isEmpty())
198                         checkInitialSelections();
199
200                 // Description
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);
209                 fCheckBoxList
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)
215                                                                         .getFirstElement();
216                                                         if (selectedElement instanceof FilterDescriptor)
217                                                                 description
218                                                                                 .setText(((FilterDescriptor) selectedElement)
219                                                                                                 .getDescription());
220                                                 }
221                                         }
222                                 });
223                 fCheckBoxList.addCheckStateListener(new ICheckStateListener() {
224                         /*
225                          * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
226                          */
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);
234                                 }
235                         }
236                 });
237
238                 addSelectionButtons(parent);
239         }
240
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);
250
251                 // Select All button
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]);
263                         }
264                 };
265                 selectButton.addSelectionListener(listener);
266
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]);
279                         }
280                 };
281                 deselectButton.addSelectionListener(listener);
282         }
283
284         private void checkInitialSelections() {
285                 Iterator itemsToCheck = getInitialElementSelections().iterator();
286                 while (itemsToCheck.hasNext())
287                         fCheckBoxList.setChecked(itemsToCheck.next(), true);
288         }
289
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]);
296                         }
297                         setResult(result);
298                 }
299                 super.okPressed();
300         }
301
302         private ILabelProvider createLabelPrivder() {
303                 return new LabelProvider() {
304                         public Image getImage(Object element) {
305                                 return null;
306                         }
307
308                         public String getText(Object element) {
309                                 if (element instanceof FilterDescriptor)
310                                         return ((FilterDescriptor) element).getName();
311                                 else
312                                         return null;
313                         }
314                 };
315         }
316
317         // ---------- result handling ----------
318
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(),
324                                         SEPARATOR);
325                 } else {
326                         fEnablePatterns = false;
327                         fPatterns = new String[0];
328                 }
329         }
330
331         /**
332          * @return the patterns which have been entered by the user
333          */
334         public String[] getUserDefinedPatterns() {
335                 return fPatterns;
336         }
337
338         /**
339          * @return the Ids of the enabled built-in filters
340          */
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()]);
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.toArray(new FilterDescriptor[result
374                                 .size()]);
375         }
376
377         public static String[] convertFromString(String patterns, String separator) {
378                 StringTokenizer tokenizer = new StringTokenizer(patterns, separator,
379                                 true);
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)) {
387                                 if (!escape)
388                                         escape = true;
389                                 else {
390                                         addPattern(result, separator);
391                                         append = true;
392                                 }
393                         } else {
394                                 if (!append)
395                                         result.add(token);
396                                 else
397                                         addPattern(result, token);
398                                 append = false;
399                                 escape = false;
400                         }
401                 }
402                 return (String[]) result.toArray(new String[result.size()]);
403         }
404
405         private static void addPattern(List list, String pattern) {
406                 if (list.isEmpty())
407                         list.add(pattern);
408                 else {
409                         int index = list.size() - 1;
410                         list.set(index, ((String) list.get(index)) + pattern);
411                 }
412         }
413
414         public static String convertToString(String[] patterns, String separator) {
415                 int length = patterns.length;
416                 StringBuffer strBuf = new StringBuffer();
417                 if (length > 0)
418                         strBuf.append(escapeSeparator(patterns[0], separator));
419                 else
420                         return ""; //$NON-NLS-1$
421                 int i = 1;
422                 while (i < length) {
423                         strBuf.append(separator);
424                         strBuf.append(" "); //$NON-NLS-1$
425                         strBuf.append(escapeSeparator(patterns[i++], separator));
426                 }
427                 return strBuf.toString();
428         }
429
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)))
436                                 buf.append(ch);
437                         buf.append(ch);
438                 }
439                 return buf.toString();
440
441         }
442 }