/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.diagram.symbollibrary.ui; import java.util.Collections; import java.util.List; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.TrayDialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.CellLabelProvider; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ColumnViewerEditor; import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.TableViewerEditor; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.simantics.diagram.symbollibrary.ui.FilterConfiguration.Mode; import org.simantics.utils.ui.ISelectionUtils; /** * @author Tuukka Lehtonen */ public class FilterDialog extends TrayDialog { private static final String FILTER_DIALOG = "FilterDialog"; //$NON-NLS-1$ private IDialogSettings dialogSettings; private Label filterTextLabel; private Text filterText; private CheckboxTableViewer filterTable; private FilterConfiguration config; private GroupFilter selectedFilter; private static class FilterLabelProvider extends LabelProvider implements ITableLabelProvider { @Override public Image getColumnImage(Object element, int columnIndex) { return null; } @Override public String getText(Object element) { return ((GroupFilter) element).getName(); } @Override public String getColumnText(Object element, int columnIndex) { return ((GroupFilter) element).getName(); } } public FilterDialog(Shell parentShell, IDialogSettings settings, FilterConfiguration config) { super(parentShell); this.config = config; dialogSettings = settings.getSection(FILTER_DIALOG); if (dialogSettings == null) dialogSettings = settings.addNewSection(FILTER_DIALOG); } @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText("Group Filters"); } @Override protected IDialogSettings getDialogBoundsSettings() { return dialogSettings; } @Override protected boolean isResizable() { return true; } @Override protected Point getInitialSize() { Point defaultSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true); Point result = super.getInitialSize(); if (defaultSize.equals(result)) return new Point(600, 500); return result; } protected Control createDialogArea(Composite parent) { Composite container = (Composite) super.createDialogArea(parent); Composite grid = new Composite(container, SWT.NONE); GridDataFactory.fillDefaults().grab(true, true).applyTo(grid); GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).applyTo(grid); Label l = new Label(grid, SWT.NONE); l.setText("Filters:"); GridDataFactory.fillDefaults().span(3, 1).applyTo(l); createFilterTable(grid); createFilterButtons(grid); createFilterConfigurationArea(grid); filterTable.setSelection(StructuredSelection.EMPTY); initializeFilterTable(); Dialog.applyDialogFont(container); return container; } private void initializeFilterTable() { if (!config.getFilters().isEmpty()) { filterTable.setSelection(new StructuredSelection(config.getFilters().iterator().next())); } } private void setFilterConfigurationEnabled(GroupFilter filter) { boolean enabled = filter !=null; filterTextLabel.setEnabled(enabled); filterText.setEnabled(enabled); if (enabled) { filterText.setText(filter.getFilterText()); } else { filterText.setText(""); } } private void createFilterTable(Composite parent) { Composite base = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().grab(true, true).applyTo(base); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(base); filterTable = CheckboxTableViewer.newCheckList(base, SWT.BORDER | SWT.MULTI); GridDataFactory.fillDefaults().grab(true, true).applyTo(filterTable.getControl()); final TableViewerColumn column = new TableViewerColumn(filterTable, SWT.LEFT); final TextCellEditor editor = new TextCellEditor(filterTable.getTable()); TableViewerEditor.create(filterTable, new ColumnViewerEditorActivationStrategy(filterTable) { @Override protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) { boolean singleSelect = ((IStructuredSelection) filterTable.getSelection()).size() == 1; boolean isLeftMouseSelect = event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION && ((MouseEvent)event.sourceEvent).button == 1; return singleSelect && (isLeftMouseSelect || event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC || event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL); } }, ColumnViewerEditor.DEFAULT); column.setLabelProvider(new CellLabelProvider() { @Override public void update(ViewerCell cell) { GroupFilter f = (GroupFilter) cell.getElement(); cell.setText(f.getName()); } }); column.setEditingSupport(new EditingSupport(filterTable) { @Override protected void setValue(Object element, Object value) { GroupFilter f = (GroupFilter) element; f.setName((String) value); Collections.sort(config.getFilters()); filterTable.refresh(); } @Override protected Object getValue(Object element) { GroupFilter f = (GroupFilter) element; return f.getName(); } @Override protected CellEditor getCellEditor(Object element) { return editor; } @Override protected boolean canEdit(Object element) { return true; } }); filterTable.setUseHashlookup(true); filterTable.setContentProvider(new ArrayContentProvider()); filterTable.setLabelProvider(new FilterLabelProvider()); //filterTable.setComparator(new ViewerComparator()); filterTable.setInput(config.getFilters()); filterTable.addCheckStateListener(new ICheckStateListener() { @Override public void checkStateChanged(CheckStateChangedEvent event) { //System.out.println("Checked: " + event.getElement() + ": " + event.getChecked()); GroupFilter gf = (GroupFilter) event.getElement(); gf.setActive(event.getChecked()); } }); filterTable.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection ss = (IStructuredSelection) event.getSelection(); selectedFilter = ISelectionUtils.filterSingleSelection(ss, GroupFilter.class); setFilterConfigurationEnabled(selectedFilter); } }); filterTable.getControl().addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { Point size = filterTable.getTable().getSize(); column.getColumn().setWidth(size.x - filterTable.getTable().getBorderWidth() * 2); } }); for (GroupFilter gf : config.getFilters()) { if (gf.isActive()) filterTable.setChecked(gf, true); } Button and = new Button(base, SWT.RADIO); and.setText("Match all filters"); and.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { setMode(FilterConfiguration.Mode.AND); } }); Button or = new Button(base, SWT.RADIO); or.setText("Match any filter"); or.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { setMode(FilterConfiguration.Mode.OR); } }); switch (config.getMode()) { case AND: and.setSelection(true); break; case OR: or.setSelection(true); break; } } protected void setMode(Mode mode) { config.setMode(mode); } private void createFilterButtons(Composite grid) { Composite buttons = new Composite(grid, SWT.NONE); GridDataFactory.fillDefaults().grab(false, false).applyTo(buttons); RowLayout rl = new RowLayout(SWT.VERTICAL); rl.fill = true; rl.marginBottom = 0; rl.marginLeft = 0; rl.marginRight = 0; rl.marginTop = 0; buttons.setLayout(rl); Button add = new Button(buttons, SWT.NONE); add.setText("&New..."); add.setToolTipText("Add New Filter"); add.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { InputDialog id = new InputDialog(getShell(), "Add New Filter", "Select Filter Name", "", new IInputValidator() { @Override public String isValid(String newText) { if (newText.trim().isEmpty()) return "Please give a non-empty name"; return null; } }); int result = id.open(); if (result != Window.OK) return; config.getFilters().add(new GroupFilter(id.getValue(), id.getValue(), false)); Collections.sort(config.getFilters()); filterTable.refresh(); } }); Button remove = new Button(buttons, SWT.NONE); remove.setText("&Remove"); remove.setToolTipText("Remove Selected Filter(s)"); remove.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { List selected = ISelectionUtils.filterSelection(filterTable.getSelection(), GroupFilter.class); for (GroupFilter f : selected) { config.getFilters().remove(f); } filterTable.refresh(); } }); // Spacer new Label(buttons, SWT.NONE); Button activateAll = new Button(buttons, SWT.NONE); activateAll.setText("&Activate All"); activateAll.setToolTipText("Activate All Filters"); activateAll.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { for (GroupFilter gf : config.getFilters()) { setActive(gf, true); } } }); Button deactivateAll = new Button(buttons, SWT.NONE); deactivateAll.setText("&Deactivate All"); deactivateAll.setToolTipText("Deactivate All Filters"); deactivateAll.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { for (GroupFilter gf : config.getFilters()) { setActive(gf, false); } } }); } private void setActive(GroupFilter group, boolean active) { //System.out.println("Set active(" + group + "): " + active); group.setActive(active); filterTable.setChecked(group, active); } private void createFilterConfigurationArea(Composite grid) { Composite base = new Composite(grid, SWT.NONE); GridDataFactory.fillDefaults().indent(12, 0).grab(true, true).applyTo(base); GridLayoutFactory.fillDefaults().numColumns(2).applyTo(base); filterTextLabel = new Label(base, SWT.NONE); filterTextLabel.setText("Group name filter:"); filterText = new Text(base, SWT.BORDER); filterText.setToolTipText("Regular Expression for Filtering by Group Name"); GridDataFactory.fillDefaults().grab(true, false).applyTo(filterText); Listener l = new Listener() { @Override public void handleEvent(Event event) { switch (event.type) { case SWT.Modify: if (selectedFilter != null) { selectedFilter.setFilterText(filterText.getText()); } break; } } }; filterText.addListener(SWT.Modify, l); } }