/*******************************************************************************
* 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
*******************************************************************************/
/*
* 7.6.2006
*/
package org.simantics.ui.workbench.dialogs;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.AbstractElementListSelectionDialog;
import org.eclipse.ui.dialogs.FilteredList;
/**
* ElementListSelectionDialog. This dialog component automatically sorts
* previously selected objects to the top of the list.
*
* The component uses title as key for distinguishing different dialog types.
*
* @author Toni Kalajainen
* @author Tuukka Lehtonen
*/
public class ElementListSelectionDialog extends AbstractElementListSelectionDialog {
/** The number of previously selected objects to be remembered */
protected static final int REMEMBER_NUM = 128;
/** The number of previously selected objects to be prioritized in the list */
protected static final int PRIORITIZE_NUM = 5;
protected String title = "";
protected List elementList = new ArrayList();
protected ILabelProvider labelProvider;
protected boolean usePreviousSelectionSort = true;
protected Label messageLabel;
protected Text filterText;
/**
* Creates a list selection dialog.
*
* @param parent the parent widget.
* @param labelProvider the label provider.
*/
public ElementListSelectionDialog(Shell parent, ILabelProvider labelProvider) {
super(parent, labelProvider);
this.labelProvider = labelProvider;
this.setIgnoreCase(true);
}
/**
* Sets the elements of the list.
* @param elements the elements of the list.
*/
public void setElements(Object... elements) {
elementList = null;
addElements(elements);
}
public void addElements(Object... elements) {
if (elementList==null)
elementList = new ArrayList();
for (Object e : elements)
elementList.add(e);
}
/**
* Sets the elements of the list.
* @param elements the elements of the list.
*/
@SuppressWarnings("rawtypes")
public void setElements(Collection c) {
elementList = null;
addElements(c);
}
@SuppressWarnings("rawtypes")
public void addElements(Collection c) {
if (elementList==null)
elementList = new ArrayList();
for (Object e : c)
elementList.add(e);
}
public void updateList() {
// Make sure that the filtered list exists before trying to update it.
if (fFilteredList != null && elementList != null) {
Object[] objs = elementList.toArray(new Object[elementList.size()]);
final boolean isEmpty = objs.length == 0;
setListElements(objs);
Runnable r = new Runnable() {
public void run() {
handleListChange(isEmpty);
}
};
Display d = getShell().getDisplay();
if (Thread.currentThread() == d.getThread())
r.run();
else
d.asyncExec(r);
}
}
protected void handleListChange(boolean isEmpty) {
boolean wasEnabled = filterText.isEnabled();
boolean enable = !isEmpty;
messageLabel.setEnabled(enable);
filterText.setEnabled(enable);
fFilteredList.setEnabled(enable);
if (!wasEnabled)
filterText.setFocus();
updateOkState();
}
/**
* Do alphabetical sort for list elements
*/
public void sortElements() {
if (elementList==null) return;
Object[] objects = elementList.toArray(new Object[0]);
Arrays.sort(objects, new Comparator() {
public int compare(Object o1, Object o2) {
String n1 = labelProvider.getText(o1).toLowerCase();
String n2 = labelProvider.getText(o2).toLowerCase();
return n1.compareTo(n2);
}});
elementList = new ArrayList(objects.length);
for (Object o : objects)
elementList.add(o);
}
/*
* @see SelectionStatusDialog#computeResult()
*/
protected void computeResult() {
setResult(Arrays.asList(getSelectedElements()));
}
@Override
public void setTitle(String title) {
super.setTitle(title);
this.title = title;
}
public void setInitialSelection(Object selectedElement) {
this.setInitialSelections(new Object[] {selectedElement});
}
/**
* Overridden just to get a hold of the message area label.
*
* @see org.eclipse.ui.dialogs.AbstractElementListSelectionDialog#createMessageArea(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Label createMessageArea(Composite composite) {
messageLabel = super.createMessageArea(composite);
return messageLabel;
}
/**
* Overridden just to get a hold of the filter text.
*
* @see org.eclipse.ui.dialogs.AbstractElementListSelectionDialog#createFilterText(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Text createFilterText(Composite parent) {
filterText = super.createFilterText(parent);
return filterText;
}
@Override
protected FilteredList createFilteredList(Composite parent) {
FilteredList flist = super.createFilteredList(parent);
if (usePreviousSelectionSort)
{
List prioritizeList = new ArrayList();
int[] previousSelections = getPreviousSelections( title );
for (int i=0; iPRIORITIZE_NUM)
break;
}
flist.setComparator(new PrioritizeComparator(prioritizeList, isCaseIgnored()));
} else {
}
return flist;
}
protected void createControls(Composite contents) {
createMessageArea(contents);
createFilterText(contents);
createFilteredList(contents);
}
/*
* @see Dialog#createDialogArea(Composite)
*/
protected Control createDialogArea(Composite parent) {
Composite contents = (Composite) super.createDialogArea(parent);
createControls(contents);
setListElements(elementList.toArray(new Object[elementList.size()]));
// Select items
setSelection(getInitialElementSelections().toArray());
// If nothing is selected, select the first element
//if (getSelectionIndices()==null || getSelectionIndices().length==0)
// this.fFilteredList.setSelection(new int[] {0});
return contents;
}
@Override
protected void okPressed() {
super.okPressed();
for (Object o : getResult())
addSelection(title, o);
}
protected static Map> previousSelections =
new HashMap>();
protected static synchronized int[] getPreviousSelections(String key)
{
List list = previousSelections.get(key);
if (list==null) return new int[0];
int result[] = new int[list.size()];
for (int i=0; i list = previousSelections.get(key);
if (list==null) {
list = new ArrayList();
previousSelections.put(key, list);
}
int hash = o.hashCode();
// remove previous
for (int i=0; iREMEMBER_NUM)
list.remove(list.size()-1);
}
public int[] getSelectionIndices() {
return super.getSelectionIndices();
}
public boolean isUsePreviousSelectionSort() {
return usePreviousSelectionSort;
}
/**
* Set usage for sorting of previous selections.
* When this sorting is enabled, the items that have been selected
* the items that have been selected previously in this same dialog
* are prioritized to appear first in the list
*
* (Dialogs are distinguished by their title :X)
*
* @param usePreviousSelectionSort
*/
public void setUsePreviousSelectionSort(boolean usePreviousSelectionSort) {
this.usePreviousSelectionSort = usePreviousSelectionSort;
}
}
class PrioritizeComparator implements Comparator
{
private final List prioritizeList;
private final boolean ignoreCase;
public PrioritizeComparator(List prioritizeList, boolean ignoreCase)
{
this.prioritizeList = prioritizeList;
this.ignoreCase = ignoreCase;
}
public int getIndex(Object o)
{
for (int i=0; i