]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/symbollibrary/ui/FilterDialog.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / symbollibrary / ui / FilterDialog.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.diagram.symbollibrary.ui;
13
14 import java.util.Collections;
15 import java.util.List;
16
17 import org.eclipse.jface.dialogs.Dialog;
18 import org.eclipse.jface.dialogs.IDialogSettings;
19 import org.eclipse.jface.dialogs.IInputValidator;
20 import org.eclipse.jface.dialogs.InputDialog;
21 import org.eclipse.jface.dialogs.TrayDialog;
22 import org.eclipse.jface.layout.GridDataFactory;
23 import org.eclipse.jface.layout.GridLayoutFactory;
24 import org.eclipse.jface.viewers.ArrayContentProvider;
25 import org.eclipse.jface.viewers.CellEditor;
26 import org.eclipse.jface.viewers.CellLabelProvider;
27 import org.eclipse.jface.viewers.CheckStateChangedEvent;
28 import org.eclipse.jface.viewers.CheckboxTableViewer;
29 import org.eclipse.jface.viewers.ColumnViewerEditor;
30 import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
31 import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
32 import org.eclipse.jface.viewers.EditingSupport;
33 import org.eclipse.jface.viewers.ICheckStateListener;
34 import org.eclipse.jface.viewers.ISelectionChangedListener;
35 import org.eclipse.jface.viewers.IStructuredSelection;
36 import org.eclipse.jface.viewers.ITableLabelProvider;
37 import org.eclipse.jface.viewers.LabelProvider;
38 import org.eclipse.jface.viewers.SelectionChangedEvent;
39 import org.eclipse.jface.viewers.StructuredSelection;
40 import org.eclipse.jface.viewers.TableViewerColumn;
41 import org.eclipse.jface.viewers.TableViewerEditor;
42 import org.eclipse.jface.viewers.TextCellEditor;
43 import org.eclipse.jface.viewers.ViewerCell;
44 import org.eclipse.jface.window.Window;
45 import org.eclipse.swt.SWT;
46 import org.eclipse.swt.events.ControlAdapter;
47 import org.eclipse.swt.events.ControlEvent;
48 import org.eclipse.swt.events.MouseEvent;
49 import org.eclipse.swt.events.SelectionAdapter;
50 import org.eclipse.swt.events.SelectionEvent;
51 import org.eclipse.swt.graphics.Image;
52 import org.eclipse.swt.graphics.Point;
53 import org.eclipse.swt.layout.RowLayout;
54 import org.eclipse.swt.widgets.Button;
55 import org.eclipse.swt.widgets.Composite;
56 import org.eclipse.swt.widgets.Control;
57 import org.eclipse.swt.widgets.Event;
58 import org.eclipse.swt.widgets.Label;
59 import org.eclipse.swt.widgets.Listener;
60 import org.eclipse.swt.widgets.Shell;
61 import org.eclipse.swt.widgets.Text;
62 import org.simantics.diagram.symbollibrary.ui.FilterConfiguration.Mode;
63 import org.simantics.utils.ui.ISelectionUtils;
64
65 /**
66  * @author Tuukka Lehtonen
67  */
68 public class FilterDialog extends TrayDialog {
69
70     private static final String FILTER_DIALOG = "FilterDialog"; //$NON-NLS-1$
71
72     private IDialogSettings     dialogSettings;
73
74     private Label               filterTextLabel;
75
76     private Text                filterText;
77
78     private CheckboxTableViewer filterTable;
79
80     private FilterConfiguration config;
81
82     private GroupFilter         selectedFilter;
83
84     private static class FilterLabelProvider extends LabelProvider implements ITableLabelProvider {
85         @Override
86         public Image getColumnImage(Object element, int columnIndex) {
87             return null;
88         }
89         @Override
90         public String getText(Object element) {
91             return ((GroupFilter) element).getName();
92         }
93         @Override
94         public String getColumnText(Object element, int columnIndex) {
95             return ((GroupFilter) element).getName();
96         }
97     }
98
99     public FilterDialog(Shell parentShell, IDialogSettings settings, FilterConfiguration config) {
100         super(parentShell);
101         this.config = config;
102
103         dialogSettings = settings.getSection(FILTER_DIALOG);
104         if (dialogSettings == null)
105             dialogSettings = settings.addNewSection(FILTER_DIALOG);
106     }
107
108     @Override
109     protected void configureShell(Shell newShell) {
110         super.configureShell(newShell);
111         newShell.setText("Group Filters");
112     }
113
114     @Override
115     protected IDialogSettings getDialogBoundsSettings() {
116         return dialogSettings;
117     }
118
119     @Override
120     protected boolean isResizable() {
121         return true;
122     }
123
124     @Override
125     protected Point getInitialSize() {
126         Point defaultSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
127         Point result = super.getInitialSize();
128         if (defaultSize.equals(result))
129             return new Point(600, 500);
130         return result;
131     }
132
133     protected Control createDialogArea(Composite parent) {
134         Composite container = (Composite) super.createDialogArea(parent);
135
136         Composite grid = new Composite(container, SWT.NONE);
137         GridDataFactory.fillDefaults().grab(true, true).applyTo(grid);
138         GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).applyTo(grid);
139
140         Label l = new Label(grid, SWT.NONE);
141         l.setText("Filters:");
142         GridDataFactory.fillDefaults().span(3, 1).applyTo(l);
143
144         createFilterTable(grid);
145         createFilterButtons(grid);
146         createFilterConfigurationArea(grid);
147
148         filterTable.setSelection(StructuredSelection.EMPTY);
149
150         initializeFilterTable();
151
152         Dialog.applyDialogFont(container);
153         return container;
154     }
155
156     private void initializeFilterTable() {
157         if (!config.getFilters().isEmpty()) {
158             filterTable.setSelection(new StructuredSelection(config.getFilters().iterator().next()));
159         }
160     }
161
162     private void setFilterConfigurationEnabled(GroupFilter filter) {
163         boolean enabled = filter !=null;
164         filterTextLabel.setEnabled(enabled);
165         filterText.setEnabled(enabled);
166
167         if (enabled) {
168             filterText.setText(filter.getFilterText());
169         } else {
170             filterText.setText("");
171         }
172     }
173
174     private void createFilterTable(Composite parent) {
175         Composite base = new Composite(parent, SWT.NONE);
176         GridDataFactory.fillDefaults().grab(true, true).applyTo(base);
177         GridLayoutFactory.fillDefaults().numColumns(1).applyTo(base);
178
179         filterTable = CheckboxTableViewer.newCheckList(base, SWT.BORDER | SWT.MULTI);
180         GridDataFactory.fillDefaults().grab(true, true).applyTo(filterTable.getControl());
181
182         final TableViewerColumn column = new TableViewerColumn(filterTable, SWT.LEFT);
183         final TextCellEditor editor = new TextCellEditor(filterTable.getTable());
184
185         TableViewerEditor.create(filterTable, new ColumnViewerEditorActivationStrategy(filterTable) {
186             @Override
187             protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
188                 boolean singleSelect = ((IStructuredSelection) filterTable.getSelection()).size() == 1;
189                 boolean isLeftMouseSelect = event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION && ((MouseEvent)event.sourceEvent).button == 1;
190                 return singleSelect && (isLeftMouseSelect
191                         || event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC
192                         || event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL);
193             }
194         }, ColumnViewerEditor.DEFAULT);
195
196         column.setLabelProvider(new CellLabelProvider() {
197             @Override
198             public void update(ViewerCell cell) {
199                 GroupFilter f = (GroupFilter) cell.getElement();
200                 cell.setText(f.getName());
201             }
202         });
203         column.setEditingSupport(new EditingSupport(filterTable) {
204             @Override
205             protected void setValue(Object element, Object value) {
206                 GroupFilter f = (GroupFilter) element;
207                 f.setName((String) value);
208                 Collections.sort(config.getFilters());
209                 filterTable.refresh();
210             }
211             @Override
212             protected Object getValue(Object element) {
213                 GroupFilter f = (GroupFilter) element;
214                 return f.getName();
215             }
216             @Override
217             protected CellEditor getCellEditor(Object element) {
218                 return editor;
219             }
220             @Override
221             protected boolean canEdit(Object element) {
222                 return true;
223             }
224         });
225
226         filterTable.setUseHashlookup(true);
227         filterTable.setContentProvider(new ArrayContentProvider());
228         filterTable.setLabelProvider(new FilterLabelProvider());
229         //filterTable.setComparator(new ViewerComparator());
230         filterTable.setInput(config.getFilters());
231
232         filterTable.addCheckStateListener(new ICheckStateListener() {
233             @Override
234             public void checkStateChanged(CheckStateChangedEvent event) {
235                 //System.out.println("Checked: " + event.getElement() + ": " + event.getChecked());
236                 GroupFilter gf = (GroupFilter) event.getElement();
237                 gf.setActive(event.getChecked());
238             }
239         });
240
241         filterTable.addSelectionChangedListener(new ISelectionChangedListener() {
242             @Override
243             public void selectionChanged(SelectionChangedEvent event) {
244                 IStructuredSelection ss = (IStructuredSelection) event.getSelection();
245                 selectedFilter = ISelectionUtils.filterSingleSelection(ss, GroupFilter.class);
246                 setFilterConfigurationEnabled(selectedFilter);
247             }
248         });
249
250         filterTable.getControl().addControlListener(new ControlAdapter() {
251             @Override
252             public void controlResized(ControlEvent e) {
253                 Point size = filterTable.getTable().getSize();
254                 column.getColumn().setWidth(size.x - filterTable.getTable().getBorderWidth() * 2);
255             }
256         });
257
258         for (GroupFilter gf : config.getFilters()) {
259             if (gf.isActive())
260                 filterTable.setChecked(gf, true);
261         }
262
263         Button and = new Button(base, SWT.RADIO);
264         and.setText("Match all filters");
265         and.addListener(SWT.Selection, new Listener() {
266             @Override
267             public void handleEvent(Event event) {
268                 setMode(FilterConfiguration.Mode.AND);
269             }
270         });
271         Button or = new Button(base, SWT.RADIO);
272         or.setText("Match any filter");
273         or.addListener(SWT.Selection, new Listener() {
274             @Override
275             public void handleEvent(Event event) {
276                 setMode(FilterConfiguration.Mode.OR);
277             }
278         });
279         switch (config.getMode()) {
280             case AND:
281                 and.setSelection(true);
282                 break;
283             case OR:
284                 or.setSelection(true);
285                 break;
286         }
287     }
288
289     protected void setMode(Mode mode) {
290         config.setMode(mode);
291     }
292
293     private void createFilterButtons(Composite grid) {
294         Composite buttons = new Composite(grid, SWT.NONE);
295         GridDataFactory.fillDefaults().grab(false, false).applyTo(buttons);
296         RowLayout rl = new RowLayout(SWT.VERTICAL);
297         rl.fill = true;
298         rl.marginBottom = 0;
299         rl.marginLeft = 0;
300         rl.marginRight = 0;
301         rl.marginTop = 0;
302         buttons.setLayout(rl);
303
304         Button add = new Button(buttons, SWT.NONE);
305         add.setText("&New...");
306         add.setToolTipText("Add New Filter");
307         add.addSelectionListener(new SelectionAdapter() {
308             @Override
309             public void widgetSelected(SelectionEvent e) {
310                 InputDialog id = new InputDialog(getShell(), "Add New Filter", "Select Filter Name", "", new IInputValidator() {
311                     @Override
312                     public String isValid(String newText) {
313                         if (newText.trim().isEmpty())
314                             return "Please give a non-empty name";
315                         return null;
316                     }
317                 });
318                 int result = id.open();
319                 if (result != Window.OK)
320                     return;
321
322                 config.getFilters().add(new GroupFilter(id.getValue(), id.getValue(), false));
323                 Collections.sort(config.getFilters());
324                 filterTable.refresh();
325             }
326         });
327
328         Button remove = new Button(buttons, SWT.NONE);
329         remove.setText("&Remove");
330         remove.setToolTipText("Remove Selected Filter(s)");
331         remove.addSelectionListener(new SelectionAdapter() {
332             @Override
333             public void widgetSelected(SelectionEvent e) {
334                 List<GroupFilter> selected = ISelectionUtils.filterSelection(filterTable.getSelection(), GroupFilter.class);
335                 for (GroupFilter f : selected) {
336                     config.getFilters().remove(f);
337                 }
338                 filterTable.refresh();
339             }
340         });
341
342         // Spacer
343         new Label(buttons, SWT.NONE);
344
345         Button activateAll = new Button(buttons, SWT.NONE);
346         activateAll.setText("&Activate All");
347         activateAll.setToolTipText("Activate All Filters");
348         activateAll.addSelectionListener(new SelectionAdapter() {
349             @Override
350             public void widgetSelected(SelectionEvent e) {
351                 for (GroupFilter gf : config.getFilters()) {
352                     setActive(gf, true);
353                 }
354             }
355         });
356
357         Button deactivateAll = new Button(buttons, SWT.NONE);
358         deactivateAll.setText("&Deactivate All");
359         deactivateAll.setToolTipText("Deactivate All Filters");
360         deactivateAll.addSelectionListener(new SelectionAdapter() {
361             @Override
362             public void widgetSelected(SelectionEvent e) {
363                 for (GroupFilter gf : config.getFilters()) {
364                     setActive(gf, false);
365                 }
366             }
367         });
368     }
369
370     private void setActive(GroupFilter group, boolean active) {
371         //System.out.println("Set active(" + group + "): " + active);
372         group.setActive(active);
373         filterTable.setChecked(group, active);
374     }
375
376     private void createFilterConfigurationArea(Composite grid) {
377         Composite base = new Composite(grid, SWT.NONE);
378         GridDataFactory.fillDefaults().indent(12, 0).grab(true, true).applyTo(base);
379         GridLayoutFactory.fillDefaults().numColumns(2).applyTo(base);
380
381          filterTextLabel = new Label(base, SWT.NONE);
382          filterTextLabel.setText("Group name filter:");
383
384          filterText = new Text(base, SWT.BORDER);
385          filterText.setToolTipText("Regular Expression for Filtering by Group Name");
386
387          GridDataFactory.fillDefaults().grab(true, false).applyTo(filterText);
388
389          Listener l = new Listener() {
390             @Override
391             public void handleEvent(Event event) {
392                 switch (event.type) {
393                     case SWT.Modify:
394                         if (selectedFilter != null) {
395                             selectedFilter.setFilterText(filterText.getText());
396                         }
397                         break;
398                 }
399             }
400          };
401          filterText.addListener(SWT.Modify, l);
402     }
403
404 }