/******************************************************************************* * 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