/** * (c) 2011, Alejandro Serrano * Released under the terms of the EPL. */ package net.sf.eclipsefp.haskell.ui.internal.editors.cabal.forms; import java.util.HashSet; import java.util.Set; import net.sf.eclipsefp.haskell.util.PlatformUtil; import org.eclipse.core.resources.IProject; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.ui.forms.widgets.FormToolkit; /** * Form entry that shows a list with attached checkboxes, * where the user can select zero or more of them. * @author Alejandro Serrano * */ public class FormEntryMultiSelect extends FormEntry implements ICheckStateListener { ITreeContentProvider contents; CheckboxTreeViewer treeField; boolean ignoreModify = false; boolean onlyOneSelected = false; public FormEntryMultiSelect( final ITreeContentProvider contents ) { this(contents, false); } public FormEntryMultiSelect( final ITreeContentProvider contents, final boolean onlyOneSelected ) { this.contents = contents; this.onlyOneSelected = onlyOneSelected; } @Override public void init( final IProject project, final Composite parent, final FormToolkit toolkit, final int style ) { treeField = new CheckboxTreeViewer( parent, SWT.NONE ); toolkit.adapt( treeField.getControl(), true, true ); treeField.setContentProvider( contents ); treeField.setComparator( new ViewerComparator() ); treeField.addCheckStateListener( this ); treeField.setInput( project ); } @Override public Control getControl() { return this.treeField.getControl(); } public CheckboxTreeViewer getTree() { return this.treeField; } @Override public int heightHint() { return 200; } @Override public void setValue( final String value, final boolean blockNotification ) { String newValue = ( value == null ) ? "" : value; String oldValue = this.getValue(); if( newValue.equals( oldValue ) ) { return; } ignoreModify = true; String[] elements = newValue.split( "(,|\\s)" ); Set<String> set=new HashSet<>(); for( String element: elements ) { set.add(element.trim()); } for( Object o: contents.getElements( null ) ) { String s = ( String )o; if( !set.contains( s ) ) { treeField.setChecked( s, false ); } else { treeField.setChecked( s, true ); } } ignoreModify = false; if( !blockNotification ) { notifyTextValueChanged(); } } @Override public String getValue() { StringBuilder builder = new StringBuilder(); for( Object o: treeField.getCheckedElements() ) { String s = ( String )o; if( builder.length() > 0 ) { builder.append( ", "+PlatformUtil.NL ); } builder.append( s ); } return builder.toString(); } public String getNonSelectedValue() { StringBuilder builder = new StringBuilder(); for( Object o: contents.getElements( null ) ) { if( !treeField.getChecked( o ) ) { String s = ( String )o; if( builder.length() > 0 ) { builder.append( ", "+PlatformUtil.NL ); } builder.append( s ); } } return builder.toString(); } @Override public void setEditable( final boolean editable ) { this.treeField.getControl().setEnabled( editable ); } @Override public void checkStateChanged( final CheckStateChangedEvent event ) { if (onlyOneSelected) { boolean previousIgnoreModify = ignoreModify; ignoreModify = true; for (Object o : treeField.getCheckedElements()) { if (!event.getElement().equals( o )) { treeField.setChecked( o, false ); } } ignoreModify = previousIgnoreModify; } if( !ignoreModify ) { notifyTextValueChanged(); } } }