/* * 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.editors.model; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import net.rim.ejde.internal.model.BasicBlackBerryProperties.AlternateEntryPoint; import net.rim.ejde.internal.model.BasicBlackBerryProperties.Icon; import net.rim.ejde.internal.model.BlackBerryProject; import net.rim.ejde.internal.model.BlackBerryProperties; import net.rim.ejde.internal.ui.editors.model.BlackBerryProjectPropertiesPage.Action; import net.rim.ejde.internal.ui.editors.model.BlackBerryProjectPropertiesPage.FilePathOperationSelectionListener; import net.rim.ejde.internal.ui.editors.model.BlackBerryProjectPropertiesPage.TableSelectionListener; import net.rim.ejde.internal.ui.editors.model.factories.ControlFactory; import net.rim.ejde.internal.ui.editors.model.factories.LayoutFactory; import net.rim.ejde.internal.util.Messages; import org.apache.commons.lang.StringUtils; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; /** * This class creates the alternate entry point section used in the project properties editor. * * @author jkeshavarzi * */ public class AlternateEntryPointSection extends AbstractSection { private TableViewer _alternateEntryPointsTableViewer; private ArrayList< AlternateEntryPoint > _aeps = new ArrayList< AlternateEntryPoint >(); private Map< Action, Button > _actionButtons; private Composite _client; /** * This class creates the AEP section used in the project properties editor. * * @param page * @param parent * @param toolkit * @param style */ public AlternateEntryPointSection( BlackBerryProjectPropertiesPage page, Composite parent, FormToolkit toolkit, int style ) { super( page, parent, page.getManagedForm().getToolkit(), ( style | Section.DESCRIPTION | ExpandableComposite.TITLE_BAR ) ); createFormContent( getSection(), toolkit ); } protected void createFormContent( Section section, FormToolkit toolkit ) { preBuild(); GridData gd = new GridData( GridData.FILL_BOTH ); gd.minimumWidth = 250; section.setLayout( LayoutFactory.createClearGridLayout( false, 1 ) ); section.setLayoutData( gd ); section.setDescription( Messages.AlternateEntryPointSection_Description ); _client = toolkit.createComposite( section ); _client.setLayout( LayoutFactory.createSectionGridLayout( false, 3 ) ); section.setClient( _client ); build( _client, toolkit ); postBuild( _client, toolkit ); } private void preBuild() { getSection().setText( Messages.AlternateEntryPointSection_Title ); getEditor().addListener( new PropertyListener() ); } private void build( Composite body, FormToolkit toolkit ) { Map< Action, SelectionListener > actionListeners; actionListeners = new HashMap< Action, SelectionListener >( Action.values().length ); actionListeners.put( Action.ADD, new FilePathAddSelectionListener( getProjectPropertiesPage() ) ); actionListeners.put( Action.REMOVE, new FilePathDeleteSelectionListener( getProjectPropertiesPage() ) ); actionListeners.put( Action.MOVE_UP, new MoveUpSelectionListener( getProjectPropertiesPage() ) ); actionListeners.put( Action.MOVE_DOWN, new MoveDownSelectionListener( getProjectPropertiesPage() ) ); setProjectType( getEditor().getBlackBerryProject().getProperties()._application.getType() ); _alternateEntryPointsTableViewer = (TableViewer) ControlFactory.buildTableControl( body, toolkit, null, Messages.AlternateEntryPointSection_ToolTip, SWT.NONE, 2, new String[] { "entry point:" }, new AEPContentProvider(), new AEPLabelProvider(), null ); //$NON-NLS-1$ _actionButtons = ControlFactory.buildButtonControls( actionListeners, body, toolkit ); // Set the heightHint of the control to match the height of its detail section Table table = _alternateEntryPointsTableViewer.getTable(); table.setData( BlackBerryProjectPropertiesPage.TABLE_TEXT_INDEX_KEY, 0 ); GridData gridData = ( (GridData) table.getLayoutData() ); gridData.heightHint = 370; table.addSelectionListener( new TableSelectionListener( _actionButtons ) ); _alternateEntryPointsTableViewer.addSelectionChangedListener( new ISelectionChangedListener() { @Override public void selectionChanged( SelectionChangedEvent event ) { getProjectPropertiesPage().getManagedForm().fireSelectionChanged( getPart(), event.getSelection() ); } } ); insertControlValuesFromModel( getProjectPropertiesPage().getBlackBerryProject().getProperties() ); if( getProjectType().equals( BlackBerryProject.LIBRARY ) ) { setEnabled( false ); getProjectPropertiesPage().getManagedForm().getForm() .setText( Messages.BlackBerryProjectAlternateEntryPointPage_Page_Title_Disabled ); } } private void postBuild( Composite body, FormToolkit toolkit ) { toolkit.paintBordersFor( body ); } @Override public void commit( boolean onSave ) { BlackBerryProjectAlternateEntryPointPage page = (BlackBerryProjectAlternateEntryPointPage) getProjectPropertiesPage(); BlackBerryProperties properties = page.getBlackBerryProject().getProperties(); AlternateEntryPoint aeps[] = page.getAlternateEntryPoints( onSave ); // Link any missing external icons from each aep for( AlternateEntryPoint aep : aeps ) { Icon icons[] = aep.getIconFiles(); if( icons.length > 0 ) { getEditor().linkExternalIcons( icons ); if( page.getAlternateEntryPointDetails() != null ) { page.getAlternateEntryPointDetails().getIconsSection().setViewerInput( icons ); } } } properties.setAlternateEntryPoints( aeps ); super.commit( onSave ); } /** * Update the controls within this section with values from the given properties object * * @param properties */ public void insertControlValuesFromModel( BlackBerryProperties properties ) { AlternateEntryPoint[] modelAepList = properties.getAlternateEntryPoints(); _aeps.clear(); _aeps.addAll( Arrays.asList( modelAepList ) ); _alternateEntryPointsTableViewer.setInput( _aeps ); _alternateEntryPointsTableViewer.refresh(); } public void setEnabled( Boolean enabled ) { Table table = _alternateEntryPointsTableViewer.getTable(); int selectionIndex = table.getSelectionIndex(); int itemCount = table.getItemCount(); int selectionCount = table.getSelectionCount(); getSection().setEnabled( enabled ); _actionButtons.get( Action.ADD ).setEnabled( enabled ); _actionButtons.get( Action.REMOVE ).setEnabled( selectionCount > 0 ? enabled : false ); _actionButtons.get( Action.MOVE_UP ).setEnabled( selectionIndex > 0 ? enabled : false ); _actionButtons.get( Action.MOVE_DOWN ) .setEnabled( selectionCount > 0 && selectionIndex < itemCount - 1 ? enabled : false ); } /** * @return The AEP table viewer used in this section. */ public TableViewer getAlternateEntryPointsTableViewer() { return _alternateEntryPointsTableViewer; } /** * @return An array of the current AlternateEntryPoint objects as shown in the view. */ public AlternateEntryPoint[] getAlternateEntryPoints() { return _aeps.toArray( new AlternateEntryPoint[ _aeps.size() ] ); } /** * Returns a list of the titles of all installed alternate entry points * * @return */ public List< String > getAepTitles() { List< String > aepTitles = new ArrayList< String >(); for( AlternateEntryPoint aep : _aeps ) { aepTitles.add( aep.getTitle() ); } return aepTitles; } private boolean aepExists( AlternateEntryPoint aepToSearch ) { for( AlternateEntryPoint aep : _aeps ) { if( aep.getTitle().equals( aepToSearch.getTitle() ) ) { return true; } } return false; } private void moveSelection( int index ) { IStructuredSelection selection = (IStructuredSelection) _alternateEntryPointsTableViewer.getSelection(); _aeps.remove( selection.getFirstElement() ); _aeps.add( index, (AlternateEntryPoint) selection.getFirstElement() ); _alternateEntryPointsTableViewer.setInput( _aeps ); _alternateEntryPointsTableViewer.refresh(); } /** * The content provider used by the AlternateEntryPoint table viewer * * @author jkeshavarzi * */ private class AEPContentProvider implements IStructuredContentProvider { @SuppressWarnings("unchecked") @Override public Object[] getElements( Object inputElement ) { if( inputElement instanceof ArrayList< ? > ) { ArrayList< AlternateEntryPoint > list = ( (ArrayList< AlternateEntryPoint >) inputElement ); return list.toArray(); } return new Object[ 0 ]; } @Override public void dispose() { } @Override public void inputChanged( Viewer viewer, Object oldInput, Object newInput ) { } } /** * The label provider used by the AlternateEntryPoint table viewer * * @author jkeshavarzi * */ private class AEPLabelProvider extends LabelProvider implements ITableLabelProvider { @Override public String getColumnText( Object obj, int index ) { if( obj instanceof AlternateEntryPoint ) { AlternateEntryPoint aep = (AlternateEntryPoint) obj; return aep.getTitle(); } return ""; //$NON-NLS-1$ } @Override public Image getColumnImage( Object obj, int index ) { return null; } } /** * A listener that listens for add aep events. This listener is trigger when the user pressed add and allows the user to * create a new AEP. * * @author jkeshavarzi * */ private class FilePathAddSelectionListener extends FilePathOperationSelectionListener { public FilePathAddSelectionListener( BlackBerryProjectPropertiesPage page ) { page.super( getPart() ); } @Override protected boolean process( SelectionEvent evt ) { InputDialog dialog = new InputDialog( _client.getShell(), Messages.AlternateEntryPointSection_Add_Dialog_Title, Messages.AlternateEntryPointSection_Add_Dialog_Label, "", null ); //$NON-NLS-1$ if( dialog.open() == InputDialog.OK ) { String dialogValue = dialog.getValue().trim(); if( !StringUtils.isEmpty( dialogValue ) ) { AlternateEntryPoint aep = new AlternateEntryPoint( dialogValue, null, null, null, null, null, null, null, null, null, null, null, null, null ); if( !aepExists( aep ) ) { _aeps.add( aep ); _alternateEntryPointsTableViewer.refresh(); getProjectPropertiesPage().selectItemInViewer( _alternateEntryPointsTableViewer, aep.getTitle(), _actionButtons ); return true; } } } return false; } } /** * The listener used for the remove AEP event. When the remove button is pressed, the selected AEP reference is deleted and * its table item is removed. * * @author jkeshavarzi * */ private class FilePathDeleteSelectionListener extends FilePathOperationSelectionListener { public FilePathDeleteSelectionListener( BlackBerryProjectPropertiesPage page ) { page.super( getPart() ); } @Override protected boolean process( SelectionEvent e ) { Table table = _alternateEntryPointsTableViewer.getTable(); Integer selectionIndex = table.getSelectionIndex(); if( selectionIndex != -1 ) { StructuredSelection selection = (StructuredSelection) _alternateEntryPointsTableViewer.getSelection(); Object selectedElement = selection.getFirstElement(); _aeps.remove( selectedElement ); getProjectPropertiesPage().removeSelectedTableItem( _alternateEntryPointsTableViewer, _actionButtons, false ); return true; } return false; } } /** * MoveUpSelectionListener * * @author bkurz * */ private class MoveUpSelectionListener extends FilePathOperationSelectionListener { protected MoveUpSelectionListener( BlackBerryProjectPropertiesPage page ) { page.super( getPart() ); } @Override protected boolean process( SelectionEvent e ) { int selectionIndex = _alternateEntryPointsTableViewer.getTable().getSelectionIndex(); moveSelection( _alternateEntryPointsTableViewer.getTable().getSelectionIndex() - 1 ); if( selectionIndex - 1 == 0 ) { _actionButtons.get( Action.MOVE_UP ).setEnabled( false ); } if( selectionIndex - 1 < _alternateEntryPointsTableViewer.getTable().getItemCount() - 1 ) { _actionButtons.get( Action.MOVE_DOWN ).setEnabled( true ); } return true; } } /** * MoveDownSelectionListener * * @author bkurz * */ private class MoveDownSelectionListener extends FilePathOperationSelectionListener { protected MoveDownSelectionListener( BlackBerryProjectPropertiesPage page ) { page.super( getPart() ); } @Override protected boolean process( SelectionEvent e ) { int selectionIndex = _alternateEntryPointsTableViewer.getTable().getSelectionIndex(); moveSelection( _alternateEntryPointsTableViewer.getTable().getSelectionIndex() + 1 ); if( selectionIndex + 1 > 0 ) { _actionButtons.get( Action.MOVE_UP ).setEnabled( true ); } if( selectionIndex + 1 == _alternateEntryPointsTableViewer.getTable().getItemCount() - 1 ) { _actionButtons.get( Action.MOVE_DOWN ).setEnabled( false ); } return true; } } private class PropertyListener implements PropertyChangeListener { @Override public void propertyChange( PropertyChangeEvent evt ) { String property = evt.getPropertyName(); if( property.equals( Messages.GeneralSection_Application_Type_Label ) ) { Object obj = evt.getNewValue(); if( obj instanceof String ) { setProjectType( (String) obj ); boolean isLibrary = getProjectType().equals( BlackBerryProject.LIBRARY ); setEnabled( !isLibrary ); getProjectPropertiesPage() .getManagedForm() .getForm() .setText( isLibrary ? Messages.BlackBerryProjectAlternateEntryPointPage_Page_Title_Disabled : Messages.BlackBerryProjectAlternateEntryPointPage_Page_Title ); } } } } }