blob: c75ecc172ca3436cec4799b01390e054d8b6b3f2 [file] [log] [blame]
/******************************************************************************
* 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;
}
}