// Copyright (c) 2003-2005 by Leif Frenzel - see http://leiffrenzel.de package net.sf.eclipsefp.haskell.ui.wizards; import java.util.ArrayList; import java.util.List; import net.sf.eclipsefp.haskell.core.code.EHaskellCommentStyle; import net.sf.eclipsefp.haskell.core.code.ModuleCreationInfo; import net.sf.eclipsefp.haskell.core.preferences.ICorePreferenceNames; import net.sf.eclipsefp.haskell.core.util.ResourceUtil; import net.sf.eclipsefp.haskell.ui.dialog.FolderSelectionDialog; import net.sf.eclipsefp.haskell.ui.dialog.SourceFolderSelectionDialog; import net.sf.eclipsefp.haskell.ui.dialog.dialogfields.DialogField; import net.sf.eclipsefp.haskell.ui.dialog.dialogfields.IDialogFieldListener; import net.sf.eclipsefp.haskell.ui.dialog.dialogfields.IStringButtonAdapter; import net.sf.eclipsefp.haskell.ui.dialog.dialogfields.Separator; import net.sf.eclipsefp.haskell.ui.dialog.dialogfields.StringButtonDialogField; import net.sf.eclipsefp.haskell.ui.dialog.dialogfields.StringDialogField; import net.sf.eclipsefp.haskell.ui.internal.util.UITexts; import net.sf.eclipsefp.haskell.ui.util.DefaultStatus; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.window.Window; 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.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.model.WorkbenchViewerComparator; /** <p>The single page for the 'New Module' wizard.</p> * * @author Leif Frenzel */ public class NewModuleWizardPage extends StatusWizardPage implements IModuleCreationInfoProvider { private StringButtonDialogField dlgFieldSourceFolder; private StringButtonDialogField dlgFieldFolders; private StringDialogField dlgFieldName; private Button dlgFieldFoldersQualify; private IStatus sourceFolderStatus; private IStatus folderStatus; private IStatus nameStatus; private final ModuleCreationInfo currentInfo; private Button chkUseLiterate; private Group grpLiterate; private Button rdoLiterate; private Button rdoTex; private ComboViewer cvTemplates; private TemplateDef defTemplate; public NewModuleWizardPage() { super( "NewModuleWizardPage" ); //$NON-NLS-1$ setTitle( UITexts.NewModuleWizardPage_1 ); setDescription( UITexts.NewModuleWizardPage_2 ); currentInfo = new ModuleCreationInfo(); createDlgFieldSourceFolder(); createDlgFieldFolder(); createDlgFieldName(); sourceFolderStatus = new DefaultStatus(); folderStatus = new DefaultStatus(); nameStatus = new DefaultStatus(); } @Override public ModuleCreationInfo getInfo() { if (chkUseLiterate.getSelection()) { if (rdoLiterate.getSelection()) { currentInfo.setCommentStyle(EHaskellCommentStyle.LITERATE); } else { currentInfo.setCommentStyle(EHaskellCommentStyle.TEX); } } else { currentInfo.setCommentStyle(EHaskellCommentStyle.USUAL); } return currentInfo; //return new ModuleCreationOperation( currentInfo ); } private void doDialogFieldChanged( final DialogField field ) { if( field == dlgFieldSourceFolder ) { IContainer sourceContainer = getCurrentlySelectedSourceContainer(); sourceFolderStatus = Validator.validateSourceFolder( sourceContainer ); // do we care if it's not a source folder as such? if( sourceFolderStatus.isOK() ) { currentInfo.setSourceContainer(sourceContainer); } } else if( field == dlgFieldFolders ) { IFolder folder = getCurrentlySelectedFolder(); if( folder != null ) { IPath sourceRelPath = ResourceUtil.getSourceRelativePath( folder ); currentInfo.setFolders( sourceRelPath ); } String text = dlgFieldFolders.getText(); folderStatus = Validator.validateFolders( text,currentInfo.isFoldersQualify() ); if( folderStatus.isOK() ) { currentInfo.setFolders( new Path( text.replace( '.', '/' ) ) ); } } else if( field == dlgFieldName ) { currentInfo.setModuleName( dlgFieldName.getText() ); nameStatus = Validator.validateModuleName( currentInfo ); } doStatusUpdate(); } private IFolder chooseFolder() { FolderSelectionDialog dialog = createFolderSelectionDialog(); IFolder selection = getCurrentlySelectedFolder(); if( selection != null ) { dialog.setInitialSelections( new Object[] { selection } ); } IFolder result = null; if( dialog.open() == Window.OK ) { result = ( IFolder )dialog.getFirstResult(); } return result; } // interface methods of DialogPage ////////////////////////////////// public void init( final IStructuredSelection selection ) { if( selection != null ) { IContainer sourceContainer = SelectionAnalyzer.getSourceContainer( selection ); currentInfo.setSourceContainer( sourceContainer ); initSourceFolderField( sourceContainer ); IPath path = SelectionAnalyzer.getSourceRelativePath( selection ); initFolderField( path ); currentInfo.setFolders( path ); } } @Override public void setVisible( final boolean visible ) { super.setVisible( visible ); if( visible ) { initAllStatus(); dlgFieldName.setFocus(); } } @Override public void createControl( final Composite parent ) { initializeDialogUnits( parent ); Composite composite = new Composite( parent, SWT.NONE ); int cols = 4; GridLayout layout = new GridLayout(); layout.numColumns = cols; composite.setLayout( layout ); createSourceFolderControls( composite, cols ); createFolderControls( composite, cols ); createSeparator( composite, cols ); createNameControls( composite, cols ); createLiterateControls( composite ); createTemplateControls(composite); setControl( composite ); Dialog.applyDialogFont( composite ); } /** * @param composite */ private void createTemplateControls( final Composite composite ) { Label l=new Label(composite,SWT.NONE); GridData gd = new GridData(); gd.horizontalAlignment = GridData.FILL; gd.grabExcessHorizontalSpace = false; gd.horizontalSpan = 2; l.setLayoutData( gd ); l.setText( UITexts.NewModuleWizardPage_template ); cvTemplates = new ComboViewer( composite,SWT.READ_ONLY ); gd = new GridData(); gd.horizontalAlignment = GridData.FILL; gd.grabExcessHorizontalSpace = false; gd.horizontalSpan = 2; cvTemplates.getCombo().setLayoutData( gd ); cvTemplates.setContentProvider( new ArrayContentProvider() ); cvTemplates.setComparator( new WorkbenchViewerComparator() ); List<TemplateDef> ltds=new ArrayList<>(); defTemplate = new TemplateDef( ICorePreferenceNames.TEMPLATE_MODULE, UITexts.preferences_project_file_TEMPLATE_MODULE ); ltds.add(defTemplate ); ltds.add( new TemplateDef( ICorePreferenceNames.TEMPLATE_MODULE_HTF, UITexts.preferences_project_file_TEMPLATE_MODULE_HTF ) ); ltds.add( new TemplateDef( ICorePreferenceNames.TEMPLATE_MODULE_TASTY, UITexts.preferences_project_file_TEMPLATE_MODULE_TASTY ) ); cvTemplates.setInput( ltds ); cvTemplates.setSelection( new StructuredSelection( defTemplate) ); cvTemplates.addSelectionChangedListener( new ISelectionChangedListener() { @Override public void selectionChanged( final SelectionChangedEvent evt ) { IStructuredSelection sel=(IStructuredSelection)evt.getSelection(); Object o=sel.getFirstElement(); if (o instanceof TemplateDef){ currentInfo.setTemplatePreferenceName(( (TemplateDef )o).getPreference()); } } } ); } private class TemplateDef{ private final String preference; private final String displayName; public TemplateDef( final String preference, final String displayName ) { super(); this.preference = preference; this.displayName = displayName; } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return this.displayName; } /** * @return the preference */ public String getPreference() { return preference; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + getOuterType().hashCode(); result = prime * result + ( ( preference == null ) ? 0 : preference.hashCode() ); return result; } @Override public boolean equals( final Object obj ) { if( this == obj ) { return true; } if( obj == null ) { return false; } if( getClass() != obj.getClass() ) { return false; } TemplateDef other = ( TemplateDef )obj; if( !getOuterType().equals( other.getOuterType() ) ) { return false; } if( preference == null ) { if( other.preference != null ) { return false; } } else if( !preference.equals( other.preference ) ) { return false; } return true; } private NewModuleWizardPage getOuterType() { return NewModuleWizardPage.this; } } private void createLiterateControls( final Composite composite ) { createUseLiterateCheckBox( composite ); createLiterateBlock(composite); } private void createUseLiterateCheckBox( final Composite composite ) { GridData gd = new GridData(); gd.horizontalAlignment = GridData.FILL; gd.grabExcessHorizontalSpace = false; gd.horizontalSpan = 1; chkUseLiterate = new Button(composite, SWT.CHECK); chkUseLiterate.setText( UITexts.NewModuleWizardPage_3 ); chkUseLiterate.setLayoutData(gd); chkUseLiterate.addSelectionListener(new SelectionListener() { @Override public void widgetSelected( final SelectionEvent e ) { enableLiterateGroup(chkUseLiterate.getSelection()); } @Override public void widgetDefaultSelected( final SelectionEvent e ) { widgetSelected( e ); } }); } private void createLiterateBlock( final Composite composite ) { createLiterateGroup( composite ); createLiterateRadio(); createTexStyleRadio(); } private void createLiterateGroup( final Composite composite ) { grpLiterate = new Group(composite, SWT.NONE); grpLiterate.setText(UITexts.NewModuleWizardPage_4); grpLiterate.setEnabled( false ); GridData gd = new GridData(); gd.horizontalAlignment = GridData.FILL; gd.grabExcessHorizontalSpace = false; gd.horizontalSpan = 4; grpLiterate.setLayoutData(gd); GridLayout layout= new GridLayout(); layout.marginHeight= 0; layout.marginWidth= 0; layout.numColumns= 1; grpLiterate.setLayout(layout); } private void createLiterateRadio() { rdoLiterate = new Button(grpLiterate, SWT.RADIO); rdoLiterate.setText(UITexts.NewModuleWizardPage_5); rdoLiterate.setEnabled( false ); rdoLiterate.setSelection(true); } private void createTexStyleRadio() { rdoTex = new Button(grpLiterate, SWT.RADIO); rdoTex.setText(UITexts.NewModuleWizardPage_6); rdoTex.setEnabled( false ); } // UI creation ////////////// private void createDlgFieldName() { FieldsAdapter adapter = new FieldsAdapter(); dlgFieldName = new StringDialogField(); dlgFieldName.setDialogFieldListener( adapter ); dlgFieldName.setLabelText( UITexts.NewModuleWizardPage_7 ); } private void createDlgFieldFolder() { FieldsAdapter adapter = new FieldsAdapter(); dlgFieldFolders = new StringButtonDialogField( adapter ); dlgFieldFolders.setDialogFieldListener( adapter ); dlgFieldFolders.setLabelText( UITexts.NewModuleWizardPage_8 ); dlgFieldFolders.setButtonLabel( UITexts.NewModuleWizardPage_9 ); adapter = new FieldsAdapter(); } private void createDlgFieldSourceFolder() { FieldsAdapter adapter = new FieldsAdapter(); dlgFieldSourceFolder = new StringButtonDialogField( adapter ); dlgFieldSourceFolder.setDialogFieldListener( adapter ); dlgFieldSourceFolder.setLabelText( UITexts.NewModuleWizardPage_10 ); dlgFieldSourceFolder.setButtonLabel( UITexts.NewModuleWizardPage_11 ); } private void initSourceFolderField( final IContainer sourceContainer ) { if( sourceContainer != null ) { String content = sourceContainer.getFullPath().toString(); dlgFieldSourceFolder.setText( content ); } } private void initFolderField( final IPath path ) { if( path != null ) { String content = path.toString(); dlgFieldFolders.setText( content.replace( '/', '.' ) ); } } private void createSourceFolderControls( final Composite parent, final int cols ) { dlgFieldSourceFolder.doFillIntoGrid( parent, cols ); int pixels = convertWidthInCharsToPixels( 40 ); Text textControl = dlgFieldSourceFolder.getTextControl( null ); setWidthHint( textControl, pixels ); } private void createFolderControls( final Composite parent, final int cols ) { dlgFieldFolders.doFillIntoGrid( parent, cols ); Text text = dlgFieldFolders.getTextControl( null ); setWidthHint( text, convertWidthInCharsToPixels( 40 ) ); Object ld = text.getLayoutData(); if( ld instanceof GridData ) { ( ( GridData )ld ).grabExcessHorizontalSpace = true; } dlgFieldFoldersQualify = new Button( parent, SWT.CHECK ); dlgFieldFoldersQualify.setSelection( true ); dlgFieldFoldersQualify.setText( UITexts.NewModuleWizardPage_FolderIsParent ); GridData gd=new GridData(); gd.horizontalSpan=cols; dlgFieldFoldersQualify.setLayoutData( gd ); dlgFieldFoldersQualify.addSelectionListener( new SelectionAdapter() { /* (non-Javadoc) * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected( final SelectionEvent e ) { currentInfo.setFoldersQualify( dlgFieldFoldersQualify.getSelection() ); folderStatus = Validator.validateFolders( dlgFieldFolders.getText(),currentInfo.isFoldersQualify() ); doStatusUpdate(); } } ); } private void createSeparator( final Composite composite, final int cols ) { Separator separator = new Separator( SWT.SEPARATOR | SWT.HORIZONTAL ); int pixels = convertHeightInCharsToPixels( 1 ); separator.doFillIntoGrid( composite, cols, pixels ); } private void createNameControls( final Composite parent, final int cols) { dlgFieldName.doFillIntoGrid( parent, cols - 1 ); DialogField.createEmptySpace( parent ); int pixels = convertWidthInCharsToPixels( 40 ); setWidthHint( dlgFieldName.getTextControl( null ), pixels ); } // event handling ///////////////// private IContainer chooseSourceFolder( final Object initElement ) { Shell shell = getShell(); SourceFolderSelectionDialog dlg = new SourceFolderSelectionDialog( shell ); dlg.setInitialSelection( initElement ); IContainer result = null; if( dlg.open() == Window.OK ) { Object element = dlg.getFirstResult(); if( element instanceof IContainer ) { result = ( IContainer )element; } } return result; } private void doChangeControlPressed( final DialogField field ) { if( field == dlgFieldFolders ) { IFolder folder = chooseFolder(); if( folder != null ) { IPath srcRelPath = ResourceUtil.getSourceRelativePath( folder ); currentInfo.setFolders( srcRelPath ); String text = srcRelPath.toString(); dlgFieldFolders.setText( text.replace( '/', '.' ) ); } } else if( field == dlgFieldSourceFolder ) { IContainer oldSourceContainer = currentInfo.getSourceContainer(); IContainer sourceFolder = chooseSourceFolder( oldSourceContainer ); if( sourceFolder != null ) { initSourceFolderField( sourceFolder ); currentInfo.setSourceContainer( sourceFolder ); } } } private void doStatusUpdate() { IStatus[] status = new IStatus[] { sourceFolderStatus, folderStatus, nameStatus }; // display the most severe status and enable/disable the ok button updateStatus( status ); } // helping methods ////////////////// /** returns the folder specified by the contents of the folders textfield, * if any, or null else (also if the specified resource does not exist). */ private IFolder getCurrentlySelectedFolder() { IFolder result = null; IPath foldersPath = new Path( dlgFieldFolders.getText().replace( '.', '/' ) ); IResource resource = getWsRoot().findMember( foldersPath ); if( resource != null && resource.exists() && resource instanceof IFolder ) { result = ( IFolder )resource; } return result; } /** returns the folder specified by the contents of the folders textfield, * if any, or null else (also if the specified resource does not exist). */ private IContainer getCurrentlySelectedSourceContainer() { IContainer result = null; IPath path = new Path( dlgFieldSourceFolder.getText() ); IResource resource = getWsRoot().findMember( path ); if( resource != null && resource.exists() && resource instanceof IContainer ) { result = ( IContainer )resource; } return result; } private IWorkspaceRoot getWsRoot() { return ResourcesPlugin.getWorkspace().getRoot(); } private void initAllStatus() { IContainer sourceContainer = currentInfo.getSourceContainer(); sourceFolderStatus = Validator.validateSourceFolder( sourceContainer ); folderStatus = Validator.validateFolders( dlgFieldFolders.getText(),currentInfo.isFoldersQualify() ); nameStatus = Validator.validateModuleName( currentInfo ); doStatusUpdate(); } private FolderSelectionDialog createFolderSelectionDialog() { IContainer sourceContainer = currentInfo.getSourceContainer(); return new FolderSelectionDialog( getShell(), sourceContainer ); } private void setWidthHint( final Control control, final int widthHint ) { Object ld = control.getLayoutData(); if( ld instanceof GridData ) { ( ( GridData )ld ).widthHint = widthHint; } } // inner classes //////////////// private void enableLiterateGroup(final boolean enabled) { if (enabled){ cvTemplates.setSelection( new StructuredSelection(defTemplate) ); cvTemplates.getCombo().notifyListeners( SWT.Selection, new Event()); } grpLiterate.setEnabled(enabled); for(Control child : grpLiterate.getChildren()) { child.setEnabled( enabled ); } cvTemplates.getCombo().setEnabled( !enabled ); } private class FieldsAdapter implements IStringButtonAdapter, IDialogFieldListener { // interface methods of IStringButtonAdapter @Override public void changeControlPressed( final DialogField field ) { doChangeControlPressed( field ); } // interface methods of IDialogFieldListener @Override public void dialogFieldChanged( final DialogField field ) { doDialogFieldChanged( field ); } } }