/* * 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.viewers.project; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; import net.rim.ejde.internal.util.ProjectUtils; import org.apache.log4j.Logger; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; 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.custom.BusyIndicator; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; /** * A tree viewer to display BlackBerry projects in a checkbox tree. * * @author dmeng * */ public class BlackBerryProjectTreeViewer extends CheckboxTreeViewer { private static final Logger _logger = Logger.getLogger( BlackBerryProjectTreeViewer.class ); private BBProjectContentProvider _contentProvider; static Comparator< IProject > ProjectNameComparator = new Comparator< IProject >() { public int compare( IProject project1, IProject project2 ) { return project1.getName().toUpperCase().compareTo( project2.getName().toUpperCase() ); } }; /** * Constructor * * @param parent */ public BlackBerryProjectTreeViewer( Composite parent, int span, int indent ) { super( parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL ); _contentProvider = new BBProjectContentProvider(); setContentProvider( _contentProvider ); setLabelProvider( new BBProjectLabelProvider() ); setAutoExpandLevel( ALL_LEVELS ); addCheckStateListener( new CheckStateListenerImpl() ); // TODO: is this needed? GridData gd = new GridData( GridData.FILL_BOTH ); gd.horizontalSpan = span; gd.horizontalIndent = indent; getTree().setLayoutData( gd ); } public BlackBerryProjectTreeViewer( Composite parent ) { this( parent, 1, 0 ); } /** * Returns the projects that should be made active based on selection */ public List< IProject > getCheckedProjects() { List< IProject > selectedProjects = new ArrayList< IProject >(); // filter the checked elements list to only include root elements // i.e. active-able elements Object[] checkedElements = getCheckedElements(); for( Object element : checkedElements ) { if( _contentProvider.getParent( element ) == null ) { selectedProjects.add( (IProject) element ); } } return selectedProjects; } public List< String > getCheckedProjectNames() { List< String > selectedProjects = new ArrayList< String >(); // filter the checked elements list to only include root elements // i.e. active-able elements Object[] checkedElements = getCheckedElements(); for( Object element : checkedElements ) { IProject project = (IProject) element; selectedProjects.add( project.getName() ); } return selectedProjects; } /** * * @param elements * type really == Project[] */ protected void initializeCheckedState( Shell shell, final Object[] elements ) { BusyIndicator.showWhile( shell.getDisplay(), new Runnable() { public void run() { setCheckedElements( elements ); } } ); } /** * Get the number of projects * * @return */ @SuppressWarnings("unchecked") public int getNumProjects() { Object input = getInput(); if( input != null ) { return ( (Collection< IProject >) input ).size(); } return 0; } public void initInput( Collection< IProject > allProjects ) { // sort the projects alphabetically List< IProject > sortedProjects = new ArrayList< IProject >(); sortedProjects.addAll( allProjects ); Collections.sort( sortedProjects, ProjectNameComparator ); setInput( sortedProjects ); } private class CheckStateListenerImpl implements ICheckStateListener { public void checkStateChanged( CheckStateChangedEvent event ) { IProject project = (IProject) event.getElement(); if( event.getChecked() ) { _logger.debug( "Checked : [" + project.getName() + "]" ); //$NON-NLS-1$ //$NON-NLS-2$ } else { _logger.debug( "Unchecked : [" + project.getName() + "]" ); //$NON-NLS-1$ //$NON-NLS-2$ } // the dependent projects are alwasy checkDependentProject( project, event.getChecked() ); } private void checkDependentProject( IProject project, boolean checked ) { Set< IProject > dependentProjects = null; try { dependentProjects = ProjectUtils.getAllReferencedProjects( project ); } catch( CoreException e ) { _logger.error( e.getMessage(), e ); } if( dependentProjects == null || dependentProjects.size() == 0 ) { return; } Tree tree = BlackBerryProjectTreeViewer.this.getTree(); TreeItem[] allItems = tree.getItems(); List< IProject > checkedProjects = BlackBerryProjectTreeViewer.this.getCheckedProjects(); for( TreeItem item : allItems ) { IProject data = (IProject) item.getData(); if( dependentProjects.contains( data ) ) { if( checked ) { if( !item.getChecked() ) { // if the dependent project is not checked, check it item.setChecked( true ); } } else { if( item.getChecked() && ( ProjectUtils.isDependedByOthers( data, checkedProjects, dependentProjects ) == null ) ) { // if the dependent project is not depended by another project, un-check it item.setChecked( false ); } } } } } } }