| /****************************************************************************** |
| * Copyright (c) 2005, 2009 IBM Corporation and others. |
| * 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: |
| * IBM Corporation - initial API and implementation |
| * Nicolas Rouquette (NASA) - Fix for Bug 260812. |
| ****************************************************************************/ |
| |
| package org.eclipse.gmf.runtime.diagram.ui.internal.dialogs.sortfilter; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.emf.transaction.TransactionalEditingDomain; |
| import org.eclipse.gef.EditPolicy; |
| import org.eclipse.gef.commands.Command; |
| import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy; |
| import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.ListCompartmentEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles; |
| import org.eclipse.gmf.runtime.diagram.ui.editpolicies.SortFilterContentEditPolicy; |
| import org.eclipse.gmf.runtime.diagram.ui.internal.properties.Properties; |
| import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages; |
| import org.eclipse.gmf.runtime.diagram.ui.requests.ChangePropertyValueRequest; |
| import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand; |
| import org.eclipse.gmf.runtime.notation.Filtering; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.GC; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| 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; |
| |
| |
| /** |
| * Simple dialog that support filtering of list compartment items through visibililty |
| * |
| * @author jcorchis |
| */ |
| public class FilterDialog |
| extends Dialog { |
| |
| /** dialog title prefix */ |
| private final String title = DiagramUIMessages.SortFilterDialog_title; |
| |
| /** filter list labels */ |
| static private final String FILTER_ITEMS_CONTAINING = DiagramUIMessages.SortFilter_filterItemsListLabel; |
| static private final String FILTER_ITEMS_LIST = DiagramUIMessages.SortFilter_fitlerListLabel; |
| |
| /** Tool tips and labels for the filter buttons */ |
| static private final String ADD_TO = DiagramUIMessages.SortFilter_addTo; |
| private final String ADD_TO_LABEL = "<"; //$NON-NLS-1$ |
| static private final String REMOVE_FROM = DiagramUIMessages.SortFilter_removeFrom; |
| private final String REMOVE_FROM_LABEL = ">"; //$NON-NLS-1$ |
| static private final String ADD_ALL = DiagramUIMessages.SortFilter_addAll; |
| private final String ADD_ALL_LABEL = "<<"; //$NON-NLS-1$ |
| static private final String REMOVE_ALL = DiagramUIMessages.SortFilter_removeAll; |
| private final String REMOVE_ALL_LABEL = ">>"; //$NON-NLS-1$ |
| static private final String APPLY = DiagramUIMessages.SortFilter_apply; |
| |
| /** List item widgets */ |
| private org.eclipse.swt.widgets.List filterList = null; |
| private org.eclipse.swt.widgets.List filters = null; |
| private Button addTo = null; |
| private Button removeFrom = null; |
| private Button addAllTo = null; |
| private Button removeAllFrom = null; |
| |
| /** Button IDs */ |
| private final int ADD_TO_ID = 1000; |
| private final int REMOVE_FROM_ID = ADD_TO_ID + 1; |
| private final int ADD_ALL_TO_ID = ADD_TO_ID + 2; |
| private final int REMOVE_ALL_FROM_ID = ADD_TO_ID + 3; |
| private final int APPLY_ID = 5000; |
| |
| /** Height (in list items) for the filter items lists */ |
| private int LIST_HEIGHT = 8; |
| |
| /** The collection Column list for this page */ |
| private Map filterMap = null; |
| private String[] filterStrings = null; |
| |
| /** the default fitlering settings */ |
| private Filtering _filtering = Filtering.NONE_LITERAL; |
| private List _filteringKeys = Collections.EMPTY_LIST; |
| |
| /** List of editpart selected */ |
| private List selection; |
| |
| /** |
| * Allows the user to initial apply changes and then |
| * only after filtering has changed. |
| */ |
| private boolean changeToApply = true; |
| |
| |
| /** |
| * SelectionAdapter for the filtering buttons. Calls <code>buttonPressed()</code> |
| * to handle the action. |
| * |
| * @author jcorchis |
| */ |
| class ButtonSelectionAdapter extends SelectionAdapter { |
| public void widgetSelected(SelectionEvent event) { |
| buttonPressed(((Integer) event.widget.getData()).intValue()); |
| } |
| } |
| |
| /** Instance of the ButtonSelectionAdapter used for all filtering buttons. */ |
| private ButtonSelectionAdapter buttonSelectionAdapter = |
| new ButtonSelectionAdapter(); |
| |
| /** |
| * @param parentShell |
| */ |
| protected FilterDialog(Shell parentShell, List selection, Map filterMap) { |
| super(parentShell); |
| this.selection = selection; |
| this.filterMap = filterMap; |
| } |
| |
| |
| /** |
| * Adds an apply button and the filter control |
| * @see org.eclipse.jface.dialogs.Dialog#createContents(org.eclipse.swt.widgets.Composite) |
| */ |
| protected Control createDialogArea(Composite parent) { |
| getShell().setText(title); |
| createFilterLists(parent); |
| return parent; |
| } |
| |
| |
| /** |
| * Adds the apply button |
| * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite) |
| */ |
| protected void createButtonsForButtonBar(Composite parent) { |
| super.createButtonsForButtonBar(parent); |
| createButton(parent, APPLY_ID, APPLY, true); |
| |
| } |
| |
| /** |
| * Creates the filtering list widgets |
| * @param parent |
| */ |
| private void createFilterLists(Composite ancestor) { |
| // Do not show the filter lists if not filter criteria |
| // is defined. |
| if (filterMap == null || filterMap.isEmpty()) |
| return; |
| |
| Object[] filterArray = filterMap.keySet().toArray(); |
| this.filterStrings = new String[filterArray.length]; |
| for (int i = 0; i < filterArray.length; i++) { |
| filterStrings[i] = (String) filterArray[i]; |
| } |
| |
| //setup layout |
| Composite parent = new Composite(ancestor, SWT.NULL); |
| |
| GridLayout layout = new GridLayout(); |
| layout.marginHeight = 10; |
| layout.marginWidth = 10; |
| layout.numColumns = 3; |
| parent.setLayout(layout); |
| |
| // Create the possible filter items list |
| Label filterItemsLabel = new Label(parent, SWT.LEFT); |
| filterItemsLabel.setText(FILTER_ITEMS_CONTAINING); |
| GridData gd = new GridData(); |
| gd.horizontalAlignment = GridData.HORIZONTAL_ALIGN_BEGINNING; |
| filterItemsLabel.setLayoutData(gd); |
| |
| // Create the possible filter items list |
| new Label(parent, SWT.LEFT); |
| |
| // Create the possible filter items list |
| Label filterItemLabel = new Label(parent, SWT.LEFT); |
| filterItemLabel.setText(FILTER_ITEMS_LIST); |
| GridData gd2 = new GridData(); |
| gd2.horizontalAlignment = GridData.BEGINNING; |
| filterItemLabel.setLayoutData(gd2); |
| |
| // Create the possible filter items list |
| filters = |
| new org.eclipse.swt.widgets.List( |
| parent, |
| SWT.MULTI | SWT.BORDER | SWT.V_SCROLL); |
| GridData gridData = new GridData(GridData.VERTICAL_ALIGN_FILL); |
| gridData.verticalSpan = 1; |
| gridData.widthHint = 80; |
| int listHeight = filters.getItemHeight() * LIST_HEIGHT; |
| Rectangle trim = filters.computeTrim(0, 0, 0, listHeight); |
| gridData.heightHint = trim.height; |
| filters.setLayoutData(gridData); |
| |
| // Create a new composite for the buttons and add |
| // stack them vertically |
| Composite buttonComposite = new Composite(parent, SWT.NULL); |
| GridLayout buttonLayout = new GridLayout(); |
| buttonLayout.marginHeight = 0; |
| buttonLayout.marginWidth = 0; |
| buttonLayout.numColumns = 1; |
| buttonComposite.setLayout(buttonLayout); |
| |
| GridData buttGD = |
| new GridData(GridData.FILL_VERTICAL | GridData.CENTER); |
| buttGD.horizontalSpan = 1; |
| buttGD.widthHint = 30; |
| buttonComposite.setLayoutData(buttGD); |
| |
| removeFrom = new Button(buttonComposite, SWT.PUSH); |
| removeFrom.setText(REMOVE_FROM_LABEL); |
| removeFrom.setToolTipText(REMOVE_FROM); |
| removeFrom.setLayoutData(makeArrowButtonGridData(removeFrom)); |
| removeFrom.setData(new Integer(REMOVE_FROM_ID)); |
| removeFrom.addSelectionListener(buttonSelectionAdapter); |
| removeFrom.setEnabled(false); |
| |
| addTo = new Button(buttonComposite, SWT.PUSH); |
| addTo.setText(ADD_TO_LABEL); |
| addTo.setToolTipText(ADD_TO); |
| addTo.setLayoutData(makeArrowButtonGridData(addTo)); |
| addTo.setData(new Integer(ADD_TO_ID)); |
| addTo.addSelectionListener(buttonSelectionAdapter); |
| addTo.setEnabled(false); |
| |
| removeAllFrom = new Button(buttonComposite, SWT.PUSH); |
| removeAllFrom.setText(REMOVE_ALL_LABEL); |
| removeAllFrom.setToolTipText(REMOVE_ALL); |
| removeAllFrom.setLayoutData(makeArrowButtonGridData(removeAllFrom)); |
| removeAllFrom.setData(new Integer(REMOVE_ALL_FROM_ID)); |
| removeAllFrom.addSelectionListener(buttonSelectionAdapter); |
| addAllTo = new Button(buttonComposite, SWT.PUSH); |
| |
| addAllTo.setText(ADD_ALL_LABEL); |
| addAllTo.setToolTipText(ADD_ALL); |
| addAllTo.setLayoutData(makeArrowButtonGridData(addAllTo)); |
| addAllTo.setData(new Integer(ADD_ALL_TO_ID)); |
| addAllTo.addSelectionListener(buttonSelectionAdapter); |
| |
| // Add the possible list of filter items |
| this.filterList = |
| new org.eclipse.swt.widgets.List( |
| parent, |
| SWT.MULTI | SWT.BORDER | SWT.V_SCROLL); |
| GridData gridData2 = new GridData(GridData.VERTICAL_ALIGN_FILL); |
| gridData2.verticalSpan = 1; |
| gridData2.widthHint = 80; |
| int listHeight2 = filterList.getItemHeight() * LIST_HEIGHT; |
| Rectangle trim2 = filterList.computeTrim(0, 0, 0, listHeight2); |
| gridData.heightHint = trim2.height; |
| filterList.setLayoutData(gridData2); |
| |
| filters.addListener(SWT.Selection, new Listener() { |
| public void handleEvent(Event e) { |
| removeFrom.setEnabled(filters.getSelectionCount() > 0); |
| } |
| }); |
| |
| filterList.addListener(SWT.Selection, new Listener() { |
| public void handleEvent(Event e) { |
| addTo.setEnabled(filterList.getSelectionCount() > 0); |
| } |
| }); |
| |
| initFilterLists(); |
| } |
| |
| /** |
| * Populates the filter lists based on the _filteringKeys |
| * and the filter criteria. |
| */ |
| private void initFilterLists() { |
| // TODO match the filtering key for all the list compartments |
| if (filterMap != null && !filterMap.isEmpty()) { |
| Set keySet = filterMap.keySet(); |
| Iterator i = keySet.iterator(); |
| if (_filtering == Filtering.AUTOMATIC_LITERAL) { |
| // Set the values of the filtered and unfiltered string |
| while (i.hasNext()) { |
| String filterString = (String) i.next(); |
| if (_filteringKeys.contains(filterString)) { |
| filters.add(filterString); |
| } else { |
| filterList.add(filterString); |
| } |
| } |
| } else { |
| // Add all filter strings to the possible filter list |
| while (i.hasNext()) { |
| String filterString = (String) i.next(); |
| filterList.add(filterString); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Creates GridData for the moveup and movedown toolbar buttons. |
| * @param control button |
| * @return the <code>GridData</code> |
| */ |
| protected GridData makeArrowButtonGridData(Control control) { |
| GC gc = new GC(control); |
| gc.setFont(control.getFont()); |
| //fill horizontal to make them all the same size |
| GridData gridData = new GridData(GridData.FILL_HORIZONTAL); |
| gridData.heightHint = 24; |
| gc.dispose(); |
| return gridData; |
| } |
| |
| /** |
| * |
| * @param filterMap |
| * @param property |
| */ |
| public void setFilter(Map filterMap, String property) { |
| if (filterMap != null) { |
| this.filterMap = filterMap; |
| Object[] filterArray = filterMap.keySet().toArray(); |
| this.filterStrings = new String[filterArray.length]; |
| for (int i = 0; i < filterArray.length; i++) { |
| filterStrings[i] = (String) filterArray[i]; |
| } |
| } |
| } |
| |
| /** |
| * Handles the button pressed event on the filter criteria. Move the items |
| * between the lists based on the selection and but button pressed. |
| * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int) |
| */ |
| protected void buttonPressed(int buttonId) { |
| String[] items = { |
| }; |
| switch (buttonId) { |
| case ADD_TO_ID : |
| items = filterList.getSelection(); |
| for (int i = 0; i < items.length; i++) { |
| filters.add(items[i]); |
| filterList.remove(items[i]); |
| } |
| addTo.setEnabled(false); |
| changeToApply = true; |
| break; |
| case REMOVE_FROM_ID : |
| items = filters.getSelection(); |
| for (int i = 0; i < items.length; i++) { |
| filterList.add(items[i]); |
| filters.remove(items[i]); |
| } |
| removeFrom.setEnabled(false); |
| changeToApply = true; |
| break; |
| case ADD_ALL_TO_ID : |
| items = filterList.getItems(); |
| for (int i = 0; i < items.length; i++) { |
| filters.add(items[i]); |
| filterList.remove(items[i]); |
| } |
| changeToApply = true; |
| break; |
| case REMOVE_ALL_FROM_ID : |
| items = filters.getItems(); |
| for (int i = 0; i < items.length; i++) { |
| filters.remove(items[i]); |
| filterList.add(items[i]); |
| } |
| changeToApply = true; |
| break; |
| case IDialogConstants.OK_ID : |
| okPressed(); |
| break; |
| case APPLY_ID : |
| applyPressed(); |
| break; |
| default: |
| super.buttonPressed(buttonId); |
| } |
| } |
| |
| /** |
| * |
| */ |
| protected void okPressed() { |
| if (changeToApply) |
| applyPressed(); |
| super.okPressed(); |
| } |
| |
| /** |
| * Executes a sort filter command for every list compartment that understands |
| * the sort filter request. |
| */ |
| protected void applyPressed() { |
| if (!changeToApply) |
| return; |
| if (filters.getItemCount() > 0) { |
| _filteringKeys = new ArrayList(); |
| _filtering = Filtering.AUTOMATIC_LITERAL; |
| for (int i = 0; i < filters.getItemCount(); i++) { |
| _filteringKeys.add(filters.getItems()[i]); |
| } |
| } else { |
| _filtering = Filtering.NONE_LITERAL; |
| _filteringKeys = Collections.EMPTY_LIST; |
| } |
| |
| ChangePropertyValueRequest filterTypeRequest = new ChangePropertyValueRequest( |
| Properties.ID_FILTERING, Properties.ID_FILTERING, |
| _filtering); |
| ChangePropertyValueRequest filterKeysRequest = new ChangePropertyValueRequest( |
| Properties.ID_FILTERING_KEYS, Properties.ID_FILTERING_KEYS, |
| _filteringKeys); |
| |
| // Run the command |
| TransactionalEditingDomain editingDomain = null; |
| List childCommands = new ArrayList(); |
| Iterator iter = selection.iterator(); |
| while (iter.hasNext()) { |
| GraphicalEditPart ep = (GraphicalEditPart) iter.next(); |
| |
| if (editingDomain == null) { |
| editingDomain = ep.getEditingDomain(); |
| } |
| |
| List children = ep.getChildren(); |
| for (int i = 0; i < children.size(); i++) { |
| if (children.get(i) instanceof ListCompartmentEditPart) { |
| ListCompartmentEditPart editPart = (ListCompartmentEditPart) children |
| .get(i); |
| |
| if (filterMap != null && filterMap.equals(getFilterMapFromEditPart(editPart))) { |
| Command command = editPart.getCommand(filterTypeRequest); |
| if (null != command) { |
| childCommands.add(new CommandProxy(command)); |
| } |
| command = editPart.getCommand(filterKeysRequest); |
| if (null != command) { |
| childCommands.add(new CommandProxy(command)); |
| } |
| } |
| } |
| } |
| } |
| |
| CompositeTransactionalCommand cc = new CompositeTransactionalCommand(editingDomain, |
| DiagramUIMessages.Command_SortFilterCommand, childCommands); |
| |
| ((IGraphicalEditPart) selection.get(0)).getRoot().getViewer() |
| .getEditDomain().getCommandStack().execute( |
| new ICommandProxy(cc)); |
| |
| changeToApply = false; |
| } |
| |
| /** |
| * Returns the ListCompartment level filter map or Collections.EMPTY_MAP |
| * if an EditPolicyRoles.SORT_FILTER_CONTENT_ROLE is not installed |
| * on the ListCompartment. |
| * @param editPart |
| * @return Map the filter map |
| */ |
| private Map getFilterMapFromEditPart(ListCompartmentEditPart editPart) { |
| |
| EditPolicy ep = editPart.getEditPolicy(EditPolicyRoles.SORT_FILTER_CONTENT_ROLE); |
| if (ep instanceof SortFilterContentEditPolicy) { |
| return ((SortFilterContentEditPolicy)ep).getFilter(); |
| } |
| |
| return Collections.EMPTY_MAP; |
| |
| } |
| } |
| |