/* * Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved. * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License, Version 1.0, * which accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html * */ package net.rim.ejde.internal.ui.wizards; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Observable; import java.util.Observer; import net.rim.ejde.internal.ui.widgets.dialog.ComboDialogField; import net.rim.ejde.internal.ui.widgets.dialog.DialogField; import net.rim.ejde.internal.ui.widgets.dialog.IDialogFieldListener; import net.rim.ejde.internal.ui.widgets.dialog.SelectionButtonDialogField; import net.rim.ejde.internal.util.Messages; import net.rim.ejde.internal.util.VMUtils; import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.internal.corext.util.JavaModelUtil; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.preferences.CompliancePreferencePage; import org.eclipse.jdt.internal.ui.preferences.PropertyAndPreferencePage; import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathSupport; import org.eclipse.jdt.launching.IVMInstall; import org.eclipse.jdt.launching.IVMInstall2; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.util.Policy; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; 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.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Link; import org.eclipse.ui.dialogs.PreferencesUtil; /** * A common UI for user to choose a BlackBerry JRE from all installed BlackBerry JREs. This is used by new project and project * import wizard. * * @author dmeng */ public class JRESelectionUI extends Observable implements Observer, SelectionListener, IDialogFieldListener { private static final String LAST_SELECTED_JRE_SETTINGS_KEY = JavaUI.ID_PLUGIN + ".last.selected.project.jre"; //$NON-NLS-1$ private static final String LAST_SELECTED_JRE_KIND2_KEY = JavaUI.ID_PLUGIN + ".last.selected.jre.kind2"; //$NON-NLS-1$ public static final int DEFAULT_RE = 0; public static final int PROJECT_RE = 1; private final SelectionButtonDialogField _useDefaultRE, _useProjectRE; private final ComboDialogField _RECombo; private Group _group; private Link _preferenceLink; private IVMInstall[] _installedVMs; private String[] _RECompliance; private boolean _enabled; private boolean _fireEvent; private AbstractBlackBerryWizardPage _wizardPage; /** * Constructor. * * @param wizardPage * The <code>AbstractBlackBerryWizardPage</code> */ public JRESelectionUI( AbstractBlackBerryWizardPage wizardPage ) { _useDefaultRE = new SelectionButtonDialogField( SWT.RADIO ); _useDefaultRE.setLabelText( getDefaultJVMLabel() ); _useProjectRE = new SelectionButtonDialogField( SWT.RADIO ); _useProjectRE.setLabelText( Messages.NewBlackBerryProjectWizardPageOne_JREGroup_specific_compliance ); _RECombo = new ComboDialogField( SWT.READ_ONLY ); fillInstalledJREs( _RECombo ); _RECombo.setDialogFieldListener( this ); _useDefaultRE.setDialogFieldListener( this ); _useProjectRE.setDialogFieldListener( this ); _enabled = true; _wizardPage = wizardPage; _fireEvent = true; } /** * Creates the control. * * @param parent * The parent composite * @return The created control */ public Control createControl( Composite parent ) { _group = new Group( parent, SWT.NONE ); _group.setFont( parent.getFont() ); _group.setLayout( _wizardPage.initGridLayout( new GridLayout( 2, false ), true ) ); _group.setText( Messages.NewBlackBerryProjectWizardPageOne_JREGroup_title ); _useProjectRE.doFillIntoGrid( _group, 1 ); Combo comboControl = _RECombo.getComboControl( _group ); comboControl.setLayoutData( new GridData( GridData.FILL, GridData.CENTER, true, false ) ); Control[] controls = _useDefaultRE.doFillIntoGrid( _group, 1 ); // Fixed IDT 233814, make sure there is enough room to display the label if user change // default JRE from java to BB GridData gd = new GridData(); gd.horizontalAlignment = GridData.FILL; gd.grabExcessHorizontalSpace = true; gd.minimumWidth = 260; controls[ 0 ].setLayoutData( gd ); _preferenceLink = new Link( _group, SWT.NONE ); _preferenceLink.setFont( _group.getFont() ); _preferenceLink.setText( Messages.NewBlackBerryProjectWizardPageOne_JREGroup_link_description ); _preferenceLink.setLayoutData( new GridData( GridData.END, GridData.CENTER, false, false ) ); _preferenceLink.addSelectionListener( this ); setDefaultButtonState(); return _group; } /** * Notify observers for changes. */ protected void fireEvent() { setChanged(); notifyObservers(); } private void fillInstalledJREs( ComboDialogField comboField ) { String selectedItem = getLastSelectedJRE(); int selectionIndex = -1; if( _useProjectRE.isSelected() ) { selectionIndex = comboField.getSelectionIndex(); if( selectionIndex != -1 ) {// paranoia selectedItem = comboField.getItems()[ selectionIndex ]; } } List< IVMInstall > standins = VMUtils.getInstalledBBVMs(); _installedVMs = ( standins.toArray( new IVMInstall[ standins.size() ] ) ); Arrays.sort( _installedVMs, new Comparator< IVMInstall >() { public int compare( IVMInstall arg0, IVMInstall arg1 ) { String cc0, cc1; if( arg1 instanceof IVMInstall2 && arg0 instanceof IVMInstall2 ) { cc0 = JavaModelUtil.getCompilerCompliance( (IVMInstall2) arg0, JavaCore.VERSION_1_4 ); cc1 = JavaModelUtil.getCompilerCompliance( (IVMInstall2) arg1, JavaCore.VERSION_1_4 ); int result = cc1.compareTo( cc0 ); if( result != 0 ) return result; } return Policy.getComparator().compare( arg0.getName(), arg1.getName() ); } } ); selectionIndex = -1;// find new index String[] jreLabels = new String[ _installedVMs.length ]; _RECompliance = new String[ _installedVMs.length ]; for( int i = 0; i < _installedVMs.length; i++ ) { jreLabels[ i ] = _installedVMs[ i ].getName(); if( selectedItem != null && jreLabels[ i ].equals( selectedItem ) ) { selectionIndex = i; } if( _installedVMs[ i ] instanceof IVMInstall2 ) { _RECompliance[ i ] = JavaModelUtil.getCompilerCompliance( (IVMInstall2) _installedVMs[ i ], JavaCore.VERSION_1_4 ); } else { _RECompliance[ i ] = JavaCore.VERSION_1_4; } } // don't fire event when setting combobox items. _fireEvent = false; comboField.setItems( jreLabels ); if( selectionIndex == -1 ) { comboField.selectItem( getDefaultBBJRE() ); } else { comboField.selectItem( selectedItem ); } _fireEvent = true; } private String getDefaultBBJRE() { IVMInstall vm = VMUtils.getDefaultBBVM(); return vm != null ? vm.getName() : ""; } private String getDefaultJVMName() { IVMInstall install = JavaRuntime.getDefaultVMInstall(); if( install != null ) { return install.getName(); } else { return Messages.NewBlackBerryProjectWizardPageOne_UnknownDefaultJRE_name; } } private String getDefaultJVMLabel() { return NLS.bind( Messages.NewBlackBerryProjectWizardPageOne_JREGroup_default_compliance, getDefaultJVMName() ); } /** * @see java.util.Observer#update(Observable, Object) */ public void update( Observable o, Object arg ) { updateEnableState(); } private void setDefaultButtonState() { _useDefaultRE.setEnabled( true ); _useProjectRE.setEnabled( true ); boolean isBBDefaultRE = VMUtils.isBlackBerryRuntimeTheWorkspaceDefault(); // if the default JRE is non-BlackBerry, select project specific JRE if( !isBBDefaultRE ) { _useProjectRE.setSelection( true ); _useDefaultRE.setSelection( false ); setLastSelectedJREKind( PROJECT_RE ); } else { int kind = getLastSelectedJREKind(); _useProjectRE.setSelection( kind == PROJECT_RE ); _useDefaultRE.setSelection( kind == DEFAULT_RE ); } _RECombo.setEnabled( _useProjectRE.isSelected() ); if( _preferenceLink != null ) { _preferenceLink.setEnabled( true ); } if( _group != null ) { _group.setEnabled( true ); } } public void setDefaultJRESelected() { _useDefaultRE.setSelection( true ); _useProjectRE.setSelection( false ); setLastSelectedJREKind( DEFAULT_RE ); fireEvent(); } private void updateEnableState() { _useDefaultRE.setEnabled( _enabled ); _useProjectRE.setEnabled( _enabled ); _RECombo.setEnabled( _enabled && _useProjectRE.isSelected() ); if( _preferenceLink != null ) { _preferenceLink.setEnabled( _enabled ); } if( _group != null ) { _group.setEnabled( _enabled ); } } /** * Handle widget select event. * * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse .swt.events.SelectionEvent) */ public void widgetSelected( SelectionEvent e ) { widgetDefaultSelected( e ); } /** * Handle widget default select event. * * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org .eclipse.swt.events.SelectionEvent) */ public void widgetDefaultSelected( SelectionEvent e ) { String jreID = BuildPathSupport.JRE_PREF_PAGE_ID; String eeID = BuildPathSupport.EE_PREF_PAGE_ID; String complianceId = CompliancePreferencePage.PREF_ID; Map data = new HashMap(); data.put( PropertyAndPreferencePage.DATA_NO_LINK, Boolean.TRUE ); PreferencesUtil.createPreferenceDialogOn( e.display.getActiveShell(), jreID, new String[] { jreID, complianceId, eeID }, data ).open(); handlePossibleJVMChange(); fireEvent(); } /** * Handle possible JVM change. */ public void handlePossibleJVMChange() { _useDefaultRE.setLabelText( getDefaultJVMLabel() ); fillInstalledJREs( _RECombo ); } /** * Handle dialog field changed. * * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener * #dialogFieldChanged(org.eclipse.jdt.internal.ui.wizards.dialogfields. DialogField) */ public void dialogFieldChanged( DialogField field ) { updateEnableState(); if( field == _RECombo ) { if( _useProjectRE.isSelected() ) { storeSelectionValue( _RECombo, LAST_SELECTED_JRE_SETTINGS_KEY ); if( _fireEvent ) { fireEvent(); } } } else if( field == _useDefaultRE ) { if( _useDefaultRE.isSelected() ) { setLastSelectedJREKind( DEFAULT_RE ); _useProjectRE.setSelection( false ); fireEvent(); } } else if( field == _useProjectRE ) { if( _useProjectRE.isSelected() ) { setLastSelectedJREKind( PROJECT_RE ); _useDefaultRE.setSelection( false ); fireEvent(); } } } private void storeSelectionValue( ComboDialogField combo, String preferenceKey ) { int index = combo.getSelectionIndex(); if( index == -1 ) return; String item = combo.getItems()[ index ]; JavaPlugin.getDefault().getDialogSettings().put( preferenceKey, item ); } private String getLastSelectedJRE() { IDialogSettings settings = JavaPlugin.getDefault().getDialogSettings(); return settings.get( LAST_SELECTED_JRE_SETTINGS_KEY ); } private int getLastSelectedJREKind() { int kind = PROJECT_RE; IDialogSettings settings = JavaPlugin.getDefault().getDialogSettings(); if( settings.get( LAST_SELECTED_JRE_KIND2_KEY ) != null ) { kind = settings.getInt( LAST_SELECTED_JRE_KIND2_KEY ); } return kind; } private void setLastSelectedJREKind( int newKind ) { JavaPlugin.getDefault().getDialogSettings().put( LAST_SELECTED_JRE_KIND2_KEY, newKind ); } /** * Get selected JVM. * * @return Selected JVM or <code>null</code> if one is not found */ public IVMInstall getSelectedJVM() { if( _useProjectRE.isSelected() ) { int index = _RECombo.getSelectionIndex(); if( index >= 0 && index < _installedVMs.length ) { // paranoia return _installedVMs[ index ]; } return null; } // user selects workspace default JRE return JavaRuntime.getDefaultVMInstall(); } /** * Returns the JVM kind user selected (i.e. project specific or workspace default) * * @return The JVM kind user selected */ public int getSelectedJVMKind() { if( _useProjectRE.isSelected() ) { return PROJECT_RE; } return DEFAULT_RE; } /** * Returns the JRE container path * * @return The JRE container path */ public IPath getJREContainerPath() { if( _useProjectRE.isSelected() ) { int index = _RECombo.getSelectionIndex(); if( index >= 0 && index < _installedVMs.length ) { // paranoia return JavaRuntime.newJREContainerPath( _installedVMs[ index ] ); } } return null; } /** * Returns the selected JRE compliance level. * * @return The JRE compliance level */ public String getSelectedCompilerCompliance() { if( _useProjectRE.isSelected() ) { int index = _RECombo.getSelectionIndex(); if( index >= 0 && index < _RECompliance.length ) { // paranoia return _RECompliance[ index ]; } } return null; } /** * Set the enable/disable the UI. * * @param enabled */ public void setEnabled( boolean enabled ) { _enabled = enabled; updateEnableState(); } }