X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.ui%2Fsrc%2Forg%2Fsimantics%2Fui%2Fworkbench%2Fdialogs%2FElementListSelectionDialog.java;fp=bundles%2Forg.simantics.ui%2Fsrc%2Forg%2Fsimantics%2Fui%2Fworkbench%2Fdialogs%2FElementListSelectionDialog.java;h=fe7537012e262f9614df0ee64ebe8b57db6ba0cd;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/dialogs/ElementListSelectionDialog.java b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/dialogs/ElementListSelectionDialog.java new file mode 100644 index 000000000..fe7537012 --- /dev/null +++ b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/dialogs/ElementListSelectionDialog.java @@ -0,0 +1,343 @@ +/******************************************************************************* + * 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