/** * (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.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.model.WorkbenchLabelProvider; import org.eclipse.ui.views.navigator.ResourceComparator; /** * Form entry for selecting a file. * @author Alejandro Serrano * */ public class FormEntryFile extends FormEntry implements ICheckStateListener { public static int FILES=1; public static int DIRECTORIES=2; CheckboxTreeViewer treeField; boolean ignoreModify = false; int typeFields; public FormEntryFile() { this(FILES | DIRECTORIES); } public FormEntryFile(final int typeFields) { super(); this.typeFields = typeFields; } @Override public void init( final IProject project, final Composite parent, final FormToolkit toolkit, final int style ) { treeField = new CheckboxTreeViewer( parent, SWT.NULL ); toolkit.adapt( treeField.getControl(), true, true ); treeField.setLabelProvider( new WorkbenchLabelProvider() ); treeField.setContentProvider( new LimitedWorkbenchContentProvider( (typeFields & FILES) ==0 ) ); treeField.setComparator( new ResourceComparator( ResourceComparator.NAME ) ); treeField.addCheckStateListener( this ); treeField.setInput( project ); } @Override public Control getControl() { return treeField.getControl(); } @Override public int heightHint() { return 100; } @Override public void setValue( final String value, final boolean blockNotification ) { String newValue = ( value == null ) ? "" : value; Set<String> oldValues = this.getValues(); String[] elements = newValue.split( "," ); Set<String> ss=new HashSet<>(); for (String element : elements) { ss.add(element.trim()); } if (ss.equals( oldValues )){ return; } ignoreModify = true; setValues(ss); ignoreModify = false; /* if (!blockNotification) { notifyTextValueChanged(); } */ } protected void setValues(final Set<String> files){ LimitedWorkbenchContentProvider provider = (LimitedWorkbenchContentProvider)treeField.getContentProvider(); Set<IResource> parents=new HashSet<>(); seeChecked(provider, provider.getElements( treeField.getInput() ), files,parents); for (IResource parent:parents){ manageParentState( parent ); } } protected void seeChecked( final LimitedWorkbenchContentProvider provider, final Object[] objects, final Set<String> files,final Set<IResource> parents ) { for (Object o : objects) { IResource res = (IResource)o; if (!files.contains( res.getProjectRelativePath().toString() )) { // Not found treeField.setChecked( res, false ); } else { treeField.setChecked( res, true ); IContainer parent=res.getParent(); if (parent instanceof IFolder){ parents.add(parent); } } seeChecked(provider, provider.getChildren( o ), files,parents); } } @Override public String getValue() { StringBuilder builder = new StringBuilder(); for (String s:getValues()){ if( builder.length() > 0 ) { builder.append( ", "+PlatformUtil.NL); } builder.append( s ); } return builder.toString(); } private Set<String> getValues(){ Set<String> vals=new HashSet<String>(); for( Object o: treeField.getCheckedElements() ) { IResource res = ( IResource )o; if ((typeFields & DIRECTORIES)==0){ if (res instanceof IFolder){ continue; } } if ((typeFields & FILES)==0){ if (res instanceof IFile){ continue; } } IPath path = res.getProjectRelativePath(); vals.add( path.toString() ); } return vals; } @Override public void setEditable( final boolean editable ) { treeField.getControl().setEnabled( editable ); } @Override public void checkStateChanged( final CheckStateChangedEvent event ) { if( !ignoreModify ) { if (event.getElement() instanceof IFolder){ treeField.setSubtreeChecked( event.getElement(), event.getChecked() ); } notifyTextValueChanged(); } LimitedWorkbenchContentProvider provider=(LimitedWorkbenchContentProvider)treeField.getContentProvider(); Object parent=provider.getParent( event.getElement() ); manageParentState(parent); } private void manageParentState(final Object parent){ if (parent!=null && ((typeFields & DIRECTORIES)==0)){ LimitedWorkbenchContentProvider provider=(LimitedWorkbenchContentProvider)treeField.getContentProvider(); boolean gotGrayed=false; boolean gotUnchecked=false; boolean gotChecked=false; for (Object child:provider.getChildren( parent )){ boolean c=treeField.getChecked( child ); boolean g=treeField.getGrayed( child ); if (g){ gotGrayed=true; } if (c){ gotChecked=true; } else { gotUnchecked=true; } } if (gotChecked){ if (gotUnchecked || gotGrayed){ treeField.setGrayChecked( parent, true ); } else { treeField.setGrayed( parent, false ); treeField.setChecked( parent, true ); } } else if (gotGrayed){ treeField.setGrayChecked( parent, true ); } else { treeField.setGrayed( parent, false ); treeField.setChecked( parent, false ); } } } }