diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ProjectSelectionPage.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ProjectSelectionPage.java | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ProjectSelectionPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ProjectSelectionPage.java new file mode 100644 index 000000000..81c7a7346 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/exportgradle/ProjectSelectionPage.java @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.eclipse.org/org/documents/epl-v10.php + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ide.eclipse.adt.internal.wizards.exportgradle; + +import com.google.common.base.Joiner; +import com.google.common.collect.Lists; +import com.ibm.icu.text.MessageFormat; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.core.IJavaModel; +import org.eclipse.jdt.core.IJavaModelMarker; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.TableLayout; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +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.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.ui.model.WorkbenchContentProvider; +import org.eclipse.ui.model.WorkbenchLabelProvider; + +import java.util.ArrayList; +import java.util.List; + +/** + * Displays a wizard page that lets the user choose the projects for which to create Gradle build + * files. + * <p> + * Based on {@link org.eclipse.ant.internal.ui.datatransfer.AntBuildfileExportPage} + */ +public class ProjectSelectionPage extends WizardPage { + + private final ProjectSetupBuilder mBuilder; + private CheckboxTableViewer mTableViewer; + private List<IJavaProject> mSelectedJavaProjects = Lists.newArrayList(); + + public ProjectSelectionPage(ProjectSetupBuilder builder) { + super("GradleExportPage"); //$NON-NLS-1$ + mBuilder = builder; + setPageComplete(false); + setTitle(ExportMessages.PageTitle); + setDescription(ExportMessages.PageDescription); + } + + @Override + public void createControl(Composite parent) { + initializeDialogUnits(parent); + + Composite workArea = new Composite(parent, SWT.NONE); + setControl(workArea); + + workArea.setLayout(new GridLayout()); + workArea.setLayoutData(new GridData(GridData.FILL_BOTH + | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL)); + + Label title = new Label(workArea, SWT.NONE); + title.setText(ExportMessages.SelectProjects); + + Composite listComposite = new Composite(workArea, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.marginWidth = 0; + layout.makeColumnsEqualWidth = false; + listComposite.setLayout(layout); + + listComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL + | GridData.GRAB_VERTICAL | GridData.FILL_BOTH)); + + Table table = new Table(listComposite, + SWT.CHECK | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + mTableViewer = new CheckboxTableViewer(table); + table.setLayout(new TableLayout()); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + data.heightHint = 300; + table.setLayoutData(data); + mTableViewer.setContentProvider(new WorkbenchContentProvider() { + @Override + public Object[] getElements(Object element) { + if (element instanceof IJavaProject[]) { + return (IJavaProject[]) element; + } + return null; + } + }); + mTableViewer.setLabelProvider(new WorkbenchLabelProvider()); + mTableViewer.addCheckStateListener(new ICheckStateListener() { + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + if (event.getChecked()) { + mSelectedJavaProjects.add((IJavaProject) event.getElement()); + } else { + mSelectedJavaProjects.remove(event.getElement()); + } + updateEnablement(); + } + }); + + initializeProjects(); + createSelectionButtons(listComposite); + setControl(workArea); + updateEnablement(); + Dialog.applyDialogFont(parent); + } + + /** + * Creates select all/deselect all buttons. + */ + private void createSelectionButtons(Composite composite) { + Composite buttonsComposite = new Composite(composite, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginWidth = 0; + layout.marginHeight = 0; + buttonsComposite.setLayout(layout); + + buttonsComposite.setLayoutData(new GridData( + GridData.VERTICAL_ALIGN_BEGINNING)); + + Button selectAll = new Button(buttonsComposite, SWT.PUSH); + selectAll.setText(ExportMessages.SelectAll); + selectAll.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + for (int i = 0; i < mTableViewer.getTable().getItemCount(); i++) { + mSelectedJavaProjects.add((IJavaProject) mTableViewer.getElementAt(i)); + } + mTableViewer.setAllChecked(true); + updateEnablement(); + } + }); + setButtonLayoutData(selectAll); + + Button deselectAll = new Button(buttonsComposite, SWT.PUSH); + deselectAll.setText(ExportMessages.DeselectAll); + deselectAll.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + mSelectedJavaProjects.clear(); + mTableViewer.setAllChecked(false); + updateEnablement(); + } + }); + setButtonLayoutData(deselectAll); + } + + /** + * Populates the list with all the eligible projects in the workspace. + */ + private void initializeProjects() { + IWorkspaceRoot rootWorkspace = ResourcesPlugin.getWorkspace().getRoot(); + IJavaModel javaModel = JavaCore.create(rootWorkspace); + IJavaProject[] javaProjects; + try { + javaProjects = javaModel.getJavaProjects(); + } catch (JavaModelException e) { + javaProjects = new IJavaProject[0]; + } + mTableViewer.setInput(javaProjects); + // Check any necessary projects + if (mSelectedJavaProjects != null) { + mTableViewer.setCheckedElements(mSelectedJavaProjects.toArray( + new IJavaProject[mSelectedJavaProjects.size()])); + } + } + + /** + * Enables/disables the finish button on the wizard and displays error messages as needed. + */ + private void updateEnablement() { + String error = null; + try { + if (mSelectedJavaProjects.size() == 0) { + error = ExportMessages.NoProjectsError; + return; + } + + List<String> cyclicProjects; + try { + cyclicProjects = getCyclicProjects(mSelectedJavaProjects); + if (cyclicProjects.size() > 0) { + error = MessageFormat.format(ExportMessages.CyclicProjectsError, + new Object[] { Joiner.on(", ").join(cyclicProjects) }); //$NON-NLS-1$ + return; + } + + error = mBuilder.setProject(mSelectedJavaProjects); + if (error != null) { + return; + } + + } catch (CoreException ignored) { + // TODO: do something? + } + } finally { + setErrorMessage(error); + setPageComplete(error == null); + getContainer().updateButtons(); + } + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + if (visible) { + mTableViewer.getTable().setFocus(); + mBuilder.setCanFinish(false); + mBuilder.setCanGenerate(false); + } + } + + /** + * Returns given projects that have cyclic dependencies. + * + * @param javaProjects list of IJavaProject objects + * @return set of project names + */ + private List<String> getCyclicProjects(List<IJavaProject> projects) throws CoreException { + + List<String> cyclicProjects = new ArrayList<String>(); + for (IJavaProject javaProject : projects) { + if (hasCyclicDependency(javaProject)) { + cyclicProjects.add(javaProject.getProject().getName()); + } + } + return cyclicProjects; + } + + /** + * Check if given project has a cyclic dependency. + * <p> + * See {@link org.eclipse.jdt.core.tests.model.ClasspathTests.numberOfCycleMarkers} + */ + private static boolean hasCyclicDependency(IJavaProject javaProject) + throws CoreException { + IMarker[] markers = javaProject.getProject().findMarkers( + IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, + IResource.DEPTH_ONE); + for (IMarker marker : markers) { + String cycleAttr = (String) marker + .getAttribute(IJavaModelMarker.CYCLE_DETECTED); + if (cycleAttr != null && cycleAttr.equals("true")) { //$NON-NLS-1$ + return true; + } + } + return false; + } +}
\ No newline at end of file |