package net.sf.eclipsefp.haskell.ui.properties; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; import net.sf.eclipsefp.haskell.buildwrapper.BuildWrapperPlugin; import net.sf.eclipsefp.haskell.core.cabalmodel.CabalSyntax; import net.sf.eclipsefp.haskell.core.cabalmodel.ModuleInclusionType; import net.sf.eclipsefp.haskell.core.cabalmodel.PackageDescription; import net.sf.eclipsefp.haskell.core.cabalmodel.PackageDescriptionLoader; import net.sf.eclipsefp.haskell.core.cabalmodel.PackageDescriptionStanza; import net.sf.eclipsefp.haskell.core.code.ModuleCreationInfo; import net.sf.eclipsefp.haskell.ui.HaskellUIPlugin; import net.sf.eclipsefp.haskell.ui.internal.util.UITexts; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; /** * <p>Give options to expose and include modules in Cabal sections</p> * * @author JP Moresmau */ public class ModuleInclusionComposite extends Composite { private final Set<PackageDescriptionStanza> included=new HashSet<>(); private final Set<PackageDescriptionStanza> exposed=new HashSet<>(); private PackageDescriptionStanza editorStanza=null; private final Collection<Button> editorStanzaButtons=new ArrayList<>(); private final SelectionListener editorButtonL=new SelectionAdapter() { /* (non-Javadoc) * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected( final SelectionEvent e ) { if (((Button)e.widget).getSelection()){ for (Button b:editorStanzaButtons){ if (b!=e.widget){ b.setSelection( false ); } } } } }; /** * have we init at all */ private boolean init=false; public ModuleInclusionComposite( final Composite parent, final int style ) { super( parent, style ); } public void initNoSourceFolder(){ GridLayout gl=new GridLayout(1,false); setLayout( gl ); Label w=new Label(this,SWT.NONE); w.setText( UITexts.module_inclusion_nosourcefolder ); layout( true, true ); } public boolean isInit() { return init; } /** * init the composite with information from the cabal file, or if it's a new module, default inclusion * @param srcPath the path to the source folder * @param module the module name * @param isNew is the module being created? */ public void init(final IFile file,final IResource srcPath, final String module,final boolean isNew){ init=true; for (Control c:getChildren()){ c.dispose(); } included.clear(); exposed.clear(); editorStanzaButtons.clear(); try { String editor=null; if (file!=null){ editor=file.getPersistentProperty( BuildWrapperPlugin.EDITORSTANZA_PROPERTY ); } PackageDescription cabal=PackageDescriptionLoader.load( BuildWrapperPlugin.getCabalFile( srcPath.getProject() )); String path=srcPath.getProjectRelativePath().toOSString(); if (path.length()==0){ path="."; } List<PackageDescriptionStanza> l=cabal.getStanzasBySourceDir().get( path ); if (l!=null && l.size()>0){ /** defaults to the only one **/ if (l.size()==1 && editor==null ){ editor=l.get( 0 ).getName(); if (editor==null){ // library editor=""; } } GridLayout gl=new GridLayout(4,false); setLayout( gl ); GridData gdTitle=new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); gdTitle.horizontalSpan=4; Label lTitle=new Label( this, SWT.NONE ); lTitle.setText( UITexts.module_inclusion_title ); lTitle.setLayoutData( gdTitle ); Label lSection=new Label( this, SWT.NONE ); lSection.setText( UITexts.module_inclusion_field_section ); Label lInclude=new Label( this, SWT.NONE ); lInclude.setText( UITexts.module_inclusion_field_include); Label lExpose=new Label( this, SWT.NONE ); lExpose.setText( UITexts.module_inclusion_field_expose ); Label lEditor=new Label( this, SWT.NONE ); lEditor.setText( UITexts.module_inclusion_field_editor); Collections.sort( l,new Comparator<PackageDescriptionStanza>() { @Override public int compare( final PackageDescriptionStanza o1, final PackageDescriptionStanza o2 ) { return o1.toTypeName().compareToIgnoreCase( o2.toTypeName() ); } }); for (final PackageDescriptionStanza pd:l){ Label lName=new Label(this,SWT.NONE); lName.setText( pd.toTypeName() ); final Button bInclude=new Button(this,SWT.CHECK); ModuleInclusionType mit=pd.getModuleInclusionType( module ); if (pd.isMainStanza() && ModuleInclusionType.MAIN.equals( mit )){ bInclude.setEnabled( false ); } final Button bExpose=new Button(this,SWT.CHECK); bExpose.setEnabled( CabalSyntax.SECTION_LIBRARY.equals( pd.getType() ) ); final Button bEditor=new Button(this,SWT.RADIO); bEditor.setEnabled( true ); editorStanzaButtons.add( bEditor ); bEditor.addSelectionListener( editorButtonL ); bEditor.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(final SelectionEvent e) { if (bEditor.getSelection()){ editorStanza=pd; } else { editorStanza=null; } } } ); if (bInclude.isEnabled()){ bInclude.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected( final SelectionEvent e ) { if(bInclude.getSelection()){ included.add( pd ); exposed.remove( pd ); bExpose.setSelection( false ); } else { included.remove( pd ); } // bExpose.setEnabled(CabalSyntax.SECTION_LIBRARY.equals( pd.getType() ) && !bInclude.getSelection() ); } }); if (ModuleInclusionType.INCLUDED.equals( mit ) || isNew){ bInclude.setSelection( true); included.add( pd ); bExpose.setSelection( false ); if (isNew){ bInclude.notifyListeners( SWT.Selection, new Event() ); } } } if (bExpose.isEnabled()){ bExpose.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected( final SelectionEvent e ) { if(bExpose.getSelection()){ exposed.add( pd ); included.remove( pd ); bInclude.setSelection( false ); } else { exposed.remove( pd ); } // bInclude.setEnabled( !bExpose.getSelection() ); } }); if (ModuleInclusionType.EXPOSED.equals( mit ) || (isNew && !bInclude.isEnabled())){ bExpose.setSelection( true); exposed.add( pd ); bInclude.setSelection( false ); if (isNew){ bInclude.notifyListeners( SWT.Selection, new Event() ); } } } if (editor!=null){ if (editor.equals( pd.getName() ) || (editor.equals( "" ) && pd.getName()==null)){ bEditor.setSelection( true ); editorStanza=pd; } } } } layout( true, true ); } catch (CoreException ce){ HaskellUIPlugin.log( ce ); } } public Set<PackageDescriptionStanza> getExposed() { return exposed; } public Set<PackageDescriptionStanza> getIncluded() { return included; } /** * @return the editorStanza */ public PackageDescriptionStanza getEditorStanza() { return editorStanza; } public void populateInfo(final ModuleCreationInfo info){ info.setExposed( getExposed() ); info.setIncluded( getIncluded() ); info.setEditorStanza( getEditorStanza() ); } }