]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2000, 2011 IBM Corporation and others. | |
3 | * All rights reserved. This program and the accompanying materials | |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | * | |
8 | * Contributors: | |
9 | * IBM Corporation - initial API and implementation | |
10 | *******************************************************************************/ | |
11 | package org.eclipse.jdt.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 org.eclipse.swt.SWT; | |
23 | import org.eclipse.swt.events.SelectionAdapter; | |
24 | import org.eclipse.swt.events.SelectionEvent; | |
25 | import org.eclipse.swt.events.SelectionListener; | |
26 | import org.eclipse.swt.graphics.Image; | |
27 | import org.eclipse.swt.layout.GridData; | |
28 | import org.eclipse.swt.layout.GridLayout; | |
29 | import org.eclipse.swt.widgets.Button; | |
30 | import org.eclipse.swt.widgets.Composite; | |
31 | import org.eclipse.swt.widgets.Control; | |
32 | import org.eclipse.swt.widgets.Label; | |
33 | import org.eclipse.swt.widgets.Shell; | |
34 | import org.eclipse.swt.widgets.Text; | |
35 | ||
36 | import org.eclipse.core.runtime.Assert; | |
37 | ||
38 | import org.eclipse.jface.dialogs.IDialogConstants; | |
39 | import org.eclipse.jface.viewers.ArrayContentProvider; | |
40 | import org.eclipse.jface.viewers.CheckStateChangedEvent; | |
41 | import org.eclipse.jface.viewers.CheckboxTableViewer; | |
42 | import org.eclipse.jface.viewers.ICheckStateListener; | |
43 | import org.eclipse.jface.viewers.ILabelProvider; | |
44 | import org.eclipse.jface.viewers.ISelection; | |
45 | import org.eclipse.jface.viewers.ISelectionChangedListener; | |
46 | import org.eclipse.jface.viewers.IStructuredSelection; | |
47 | import org.eclipse.jface.viewers.LabelProvider; | |
48 | import org.eclipse.jface.viewers.SelectionChangedEvent; | |
49 | ||
50 | import org.eclipse.ui.PlatformUI; | |
51 | import org.eclipse.ui.dialogs.SelectionDialog; | |
52 | ||
53 | import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; | |
54 | import org.eclipse.jdt.internal.ui.util.SWTUtil; | |
55 | ||
56 | public class CustomFiltersDialog extends SelectionDialog { | |
57 | ||
58 | private static final String SEPARATOR= ","; //$NON-NLS-1$ | |
59 | ||
60 | private String fViewId; | |
61 | private boolean fEnablePatterns; | |
62 | private String[] fPatterns; | |
63 | private String[] fEnabledFilterIds; | |
64 | ||
65 | private FilterDescriptor[] fBuiltInFilters; | |
66 | ||
67 | private CheckboxTableViewer fCheckBoxList; | |
68 | private Button fEnableUserDefinedPatterns; | |
69 | private Text fUserDefinedPatterns; | |
70 | ||
71 | private Stack<FilterDescriptor> fFilterDescriptorChangeHistory; | |
72 | ||
73 | ||
74 | /** | |
75 | * Creates a dialog to customize Java element filters. | |
76 | * | |
77 | * @param shell the parent shell | |
78 | * @param viewId the id of the view | |
79 | * @param enablePatterns <code>true</code> if pattern filters are enabled | |
80 | * @param patterns the filter patterns | |
81 | * @param enabledFilterIds the Ids of the enabled filters | |
82 | */ | |
83 | public CustomFiltersDialog( | |
84 | Shell shell, | |
85 | String viewId, | |
86 | boolean enablePatterns, | |
87 | String[] patterns, | |
88 | String[] enabledFilterIds) { | |
89 | ||
90 | super(shell); | |
91 | Assert.isNotNull(viewId); | |
92 | Assert.isNotNull(patterns); | |
93 | Assert.isNotNull(enabledFilterIds); | |
94 | ||
95 | fViewId= viewId; | |
96 | fPatterns= patterns; | |
97 | fEnablePatterns= enablePatterns; | |
98 | fEnabledFilterIds= enabledFilterIds; | |
99 | ||
100 | fBuiltInFilters= FilterDescriptor.getFilterDescriptors(fViewId); | |
101 | fFilterDescriptorChangeHistory= new Stack<FilterDescriptor>(); | |
102 | } | |
103 | ||
104 | @Override | |
105 | protected void configureShell(Shell shell) { | |
106 | setTitle(FilterMessages.CustomFiltersDialog_title); | |
107 | setMessage(FilterMessages.CustomFiltersDialog_filterList_label); | |
108 | super.configureShell(shell); | |
109 | PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IJavaHelpContextIds.CUSTOM_FILTERS_DIALOG); | |
110 | } | |
111 | ||
112 | /** | |
113 | * Overrides method in Dialog | |
114 | * | |
115 | * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite) | |
116 | */ | |
117 | @Override | |
118 | protected Control createDialogArea(Composite parent) { | |
119 | initializeDialogUnits(parent); | |
120 | // create a composite with standard margins and spacing | |
121 | Composite composite= new Composite(parent, SWT.NONE); | |
122 | GridLayout layout= new GridLayout(); | |
123 | layout.marginHeight= convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); | |
124 | layout.marginWidth= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); | |
125 | layout.verticalSpacing= convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); | |
126 | layout.horizontalSpacing= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); | |
127 | composite.setLayout(layout); | |
128 | composite.setLayoutData(new GridData(GridData.FILL_BOTH)); | |
129 | composite.setFont(parent.getFont()); | |
130 | Composite group= composite; | |
131 | ||
132 | // Checkbox | |
133 | fEnableUserDefinedPatterns= new Button(group, SWT.CHECK); | |
134 | fEnableUserDefinedPatterns.setFocus(); | |
135 | fEnableUserDefinedPatterns.setText(FilterMessages.CustomFiltersDialog_enableUserDefinedPattern); | |
136 | ||
137 | // Pattern field | |
138 | fUserDefinedPatterns= new Text(group, SWT.SINGLE | SWT.BORDER); | |
139 | GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); | |
140 | data.widthHint= convertWidthInCharsToPixels(59); | |
141 | fUserDefinedPatterns.setLayoutData(data); | |
142 | String patterns= convertToString(fPatterns, SEPARATOR); | |
143 | fUserDefinedPatterns.setText(patterns); | |
144 | SWTUtil.setAccessibilityText(fUserDefinedPatterns, FilterMessages.CustomFiltersDialog_name_filter_pattern_description); | |
145 | ||
146 | // Info text | |
147 | final Label info= new Label(group, SWT.LEFT); | |
148 | info.setText(FilterMessages.CustomFiltersDialog_patternInfo); | |
149 | ||
150 | // Enabling / disabling of pattern group | |
151 | fEnableUserDefinedPatterns.setSelection(fEnablePatterns); | |
152 | fUserDefinedPatterns.setEnabled(fEnablePatterns); | |
153 | info.setEnabled(fEnablePatterns); | |
154 | fEnableUserDefinedPatterns.addSelectionListener(new SelectionAdapter() { | |
155 | @Override | |
156 | public void widgetSelected(SelectionEvent e) { | |
157 | boolean state= fEnableUserDefinedPatterns.getSelection(); | |
158 | fUserDefinedPatterns.setEnabled(state); | |
159 | info.setEnabled(fEnableUserDefinedPatterns.getSelection()); | |
160 | if (state) | |
161 | fUserDefinedPatterns.setFocus(); | |
162 | } | |
163 | }); | |
164 | ||
165 | // Filters provided by extension point | |
166 | if (fBuiltInFilters.length > 0) | |
167 | createCheckBoxList(group); | |
168 | ||
169 | applyDialogFont(parent); | |
170 | return parent; | |
171 | } | |
172 | ||
173 | private void createCheckBoxList(Composite parent) { | |
174 | // Filler | |
175 | new Label(parent, SWT.NONE); | |
176 | ||
177 | Label info= new Label(parent, SWT.LEFT); | |
178 | info.setText(FilterMessages.CustomFiltersDialog_filterList_label); | |
179 | ||
180 | fCheckBoxList= CheckboxTableViewer.newCheckList(parent, SWT.BORDER); | |
181 | GridData data= new GridData(GridData.FILL_BOTH); | |
182 | data.heightHint= fCheckBoxList.getTable().getItemHeight() * 10; | |
183 | fCheckBoxList.getTable().setLayoutData(data); | |
184 | ||
185 | fCheckBoxList.setLabelProvider(createLabelPrivder()); | |
186 | fCheckBoxList.setContentProvider(new ArrayContentProvider()); | |
187 | Arrays.sort(fBuiltInFilters); | |
188 | fCheckBoxList.setInput(fBuiltInFilters); | |
189 | setInitialSelections(getEnabledFilterDescriptors()); | |
190 | ||
191 | List<Object[]> initialSelection= getInitialElementSelections(); | |
192 | if (initialSelection != null && !initialSelection.isEmpty()) | |
193 | checkInitialSelections(); | |
194 | ||
195 | // Description | |
196 | info= new Label(parent, SWT.LEFT); | |
197 | info.setText(FilterMessages.CustomFiltersDialog_description_label); | |
198 | final Text description= new Text(parent, SWT.LEFT | SWT.WRAP | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.V_SCROLL); | |
199 | data = new GridData(GridData.FILL_HORIZONTAL); | |
200 | data.heightHint= convertHeightInCharsToPixels(3); | |
201 | description.setLayoutData(data); | |
202 | fCheckBoxList.addSelectionChangedListener(new ISelectionChangedListener() { | |
203 | public void selectionChanged(SelectionChangedEvent event) { | |
204 | ISelection selection= event.getSelection(); | |
205 | if (selection instanceof IStructuredSelection) { | |
206 | Object selectedElement= ((IStructuredSelection)selection).getFirstElement(); | |
207 | if (selectedElement instanceof FilterDescriptor) | |
208 | description.setText(((FilterDescriptor)selectedElement).getDescription()); | |
209 | } | |
210 | } | |
211 | }); | |
212 | fCheckBoxList.addCheckStateListener(new ICheckStateListener() { | |
213 | /* | |
214 | * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent) | |
215 | */ | |
216 | public void checkStateChanged(CheckStateChangedEvent event) { | |
217 | Object element= event.getElement(); | |
218 | if (element instanceof FilterDescriptor) { | |
219 | // renew if already touched | |
220 | if (fFilterDescriptorChangeHistory.contains(element)) | |
221 | fFilterDescriptorChangeHistory.remove(element); | |
222 | fFilterDescriptorChangeHistory.push((FilterDescriptor) element); | |
223 | } | |
224 | }}); | |
225 | ||
226 | addSelectionButtons(parent); | |
227 | } | |
228 | ||
229 | private void addSelectionButtons(Composite composite) { | |
230 | Composite buttonComposite= new Composite(composite, SWT.RIGHT); | |
231 | GridLayout layout= new GridLayout(); | |
232 | layout.numColumns= 2; | |
233 | buttonComposite.setLayout(layout); | |
234 | GridData data= new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.GRAB_HORIZONTAL); | |
235 | data.grabExcessHorizontalSpace= true; | |
236 | composite.setData(data); | |
237 | ||
238 | // Select All button | |
239 | String label= FilterMessages.CustomFiltersDialog_SelectAllButton_label; | |
240 | Button selectButton= createButton(buttonComposite, IDialogConstants.SELECT_ALL_ID, label, false); | |
241 | SWTUtil.setButtonDimensionHint(selectButton); | |
242 | SelectionListener listener= new SelectionAdapter() { | |
243 | @Override | |
244 | public void widgetSelected(SelectionEvent e) { | |
245 | fCheckBoxList.setAllChecked(true); | |
246 | fFilterDescriptorChangeHistory.clear(); | |
247 | for (int i= 0; i < fBuiltInFilters.length; i++) | |
248 | fFilterDescriptorChangeHistory.push(fBuiltInFilters[i]); | |
249 | } | |
250 | }; | |
251 | selectButton.addSelectionListener(listener); | |
252 | ||
253 | // De-select All button | |
254 | label= FilterMessages.CustomFiltersDialog_DeselectAllButton_label; | |
255 | Button deselectButton= createButton(buttonComposite, IDialogConstants.DESELECT_ALL_ID, label, false); | |
256 | SWTUtil.setButtonDimensionHint(deselectButton); | |
257 | listener= new SelectionAdapter() { | |
258 | @Override | |
259 | public void widgetSelected(SelectionEvent e) { | |
260 | fCheckBoxList.setAllChecked(false); | |
261 | fFilterDescriptorChangeHistory.clear(); | |
262 | for (int i= 0; i < fBuiltInFilters.length; i++) | |
263 | fFilterDescriptorChangeHistory.push(fBuiltInFilters[i]); | |
264 | } | |
265 | }; | |
266 | deselectButton.addSelectionListener(listener); | |
267 | } | |
268 | ||
269 | private void checkInitialSelections() { | |
270 | Iterator<Object[]> itemsToCheck= getInitialElementSelections().iterator(); | |
271 | while (itemsToCheck.hasNext()) | |
272 | fCheckBoxList.setChecked(itemsToCheck.next(),true); | |
273 | } | |
274 | ||
275 | @Override | |
276 | protected void okPressed() { | |
277 | if (fBuiltInFilters != null) { | |
278 | ArrayList<FilterDescriptor> result= new ArrayList<FilterDescriptor>(); | |
279 | for (int i= 0; i < fBuiltInFilters.length; ++i) { | |
280 | if (fCheckBoxList.getChecked(fBuiltInFilters[i])) | |
281 | result.add(fBuiltInFilters[i]); | |
282 | } | |
283 | setResult(result); | |
284 | } | |
285 | super.okPressed(); | |
286 | } | |
287 | ||
288 | private ILabelProvider createLabelPrivder() { | |
289 | return | |
290 | new LabelProvider() { | |
291 | @Override | |
292 | public Image getImage(Object element) { | |
293 | return null; | |
294 | } | |
295 | @Override | |
296 | public String getText(Object element) { | |
297 | if (element instanceof FilterDescriptor) | |
298 | return ((FilterDescriptor)element).getName(); | |
299 | else | |
300 | return null; | |
301 | } | |
302 | }; | |
303 | } | |
304 | ||
305 | // ---------- result handling ---------- | |
306 | ||
307 | @Override | |
308 | protected void setResult(List newResult) { | |
309 | super.setResult(newResult); | |
310 | if (fUserDefinedPatterns.getText().length() > 0) { | |
311 | fEnablePatterns= fEnableUserDefinedPatterns.getSelection(); | |
312 | fPatterns= convertFromString(fUserDefinedPatterns.getText(), SEPARATOR); | |
313 | } else { | |
314 | fEnablePatterns= false; | |
315 | fPatterns= new String[0]; | |
316 | } | |
317 | } | |
318 | ||
319 | ||
320 | /** | |
321 | * @return the patterns which have been entered by the user | |
322 | */ | |
323 | public String[] getUserDefinedPatterns() { | |
324 | return fPatterns; | |
325 | } | |
326 | ||
327 | /** | |
328 | * @return the Ids of the enabled built-in filters | |
329 | */ | |
330 | public String[] getEnabledFilterIds() { | |
331 | Object[] result= getResult(); | |
332 | Set<String> enabledIds= new HashSet<String>(result.length); | |
333 | for (int i= 0; i < result.length; i++) | |
334 | enabledIds.add(((FilterDescriptor)result[i]).getId()); | |
335 | return enabledIds.toArray(new String[enabledIds.size()]); | |
336 | } | |
337 | ||
338 | /** | |
339 | * @return <code>true</code> if the user-defined patterns are disabled | |
340 | */ | |
341 | public boolean areUserDefinedPatternsEnabled() { | |
342 | return fEnablePatterns; | |
343 | } | |
344 | ||
345 | /** | |
346 | * @return a stack with the filter descriptor check history | |
347 | * @since 3.0 | |
348 | */ | |
349 | public Stack<FilterDescriptor> getFilterDescriptorChangeHistory() { | |
350 | return fFilterDescriptorChangeHistory; | |
351 | } | |
352 | ||
353 | private FilterDescriptor[] getEnabledFilterDescriptors() { | |
354 | FilterDescriptor[] filterDescs= fBuiltInFilters; | |
355 | List<FilterDescriptor> result= new ArrayList<FilterDescriptor>(filterDescs.length); | |
356 | List<String> enabledFilterIds= Arrays.asList(fEnabledFilterIds); | |
357 | for (int i= 0; i < filterDescs.length; i++) { | |
358 | String id= filterDescs[i].getId(); | |
359 | if (enabledFilterIds.contains(id)) | |
360 | result.add(filterDescs[i]); | |
361 | } | |
362 | return result.toArray(new FilterDescriptor[result.size()]); | |
363 | } | |
364 | ||
365 | ||
366 | public static String[] convertFromString(String patterns, String separator) { | |
367 | StringTokenizer tokenizer= new StringTokenizer(patterns, separator, true); | |
368 | int tokenCount= tokenizer.countTokens(); | |
369 | List<String> result= new ArrayList<String>(tokenCount); | |
370 | boolean escape= false; | |
371 | boolean append= false; | |
372 | while (tokenizer.hasMoreTokens()) { | |
373 | String token= tokenizer.nextToken().trim(); | |
374 | if (separator.equals(token)) { | |
375 | if (!escape) | |
376 | escape= true; | |
377 | else { | |
378 | addPattern(result, separator); | |
379 | append= true; | |
380 | } | |
381 | } else { | |
382 | if (!append) | |
383 | result.add(token); | |
384 | else | |
385 | addPattern(result, token); | |
386 | append= false; | |
387 | escape= false; | |
388 | } | |
389 | } | |
390 | return result.toArray(new String[result.size()]); | |
391 | } | |
392 | ||
393 | private static void addPattern(List<String> list, String pattern) { | |
394 | if (list.isEmpty()) | |
395 | list.add(pattern); | |
396 | else { | |
397 | int index= list.size() - 1; | |
398 | list.set(index, list.get(index) + pattern); | |
399 | } | |
400 | } | |
401 | ||
402 | public static String convertToString(String[] patterns, String separator) { | |
403 | int length= patterns.length; | |
404 | StringBuffer strBuf= new StringBuffer(); | |
405 | if (length > 0) | |
406 | strBuf.append(escapeSeparator(patterns[0], separator)); | |
407 | else | |
408 | return ""; //$NON-NLS-1$ | |
409 | int i= 1; | |
410 | while (i < length) { | |
411 | strBuf.append(separator); | |
412 | strBuf.append(" "); //$NON-NLS-1$ | |
413 | strBuf.append(escapeSeparator(patterns[i++], separator)); | |
414 | } | |
415 | return strBuf.toString(); | |
416 | } | |
417 | ||
418 | private static String escapeSeparator(String pattern, String separator) { | |
419 | int length= pattern.length(); | |
420 | StringBuffer buf= new StringBuffer(length); | |
421 | for (int i= 0; i < length; i++) { | |
422 | char ch= pattern.charAt(i); | |
423 | if (separator.equals(String.valueOf(ch))) | |
424 | buf.append(ch); | |
425 | buf.append(ch); | |
426 | } | |
427 | return buf.toString(); | |
428 | ||
429 | } | |
430 | } |