aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportPage.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportPage.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportPage.java512
1 files changed, 512 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportPage.java
new file mode 100644
index 000000000..1e02fedae
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ImportPage.java
@@ -0,0 +1,512 @@
+/*
+ * Copyright (C) 2012 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.newproject;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.tools.lint.detector.api.LintUtils;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.CellLabelProvider;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerCell;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Rectangle;
+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.DirectoryDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkingSet;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/** WizardPage for importing Android projects */
+class ImportPage extends WizardPage implements SelectionListener, IStructuredContentProvider,
+ ICheckStateListener, KeyListener, TraverseListener, ControlListener {
+ private static final int DIR_COLUMN = 0;
+ private static final int NAME_COLUMN = 1;
+
+ private final NewProjectWizardState mValues;
+ private List<ImportedProject> mProjectPaths;
+ private final IProject[] mExistingProjects;
+
+ private Text mDir;
+ private Button mBrowseButton;
+ private Button mCopyCheckBox;
+ private Button mRefreshButton;
+ private Button mDeselectAllButton;
+ private Button mSelectAllButton;
+ private Table mTable;
+ private CheckboxTableViewer mCheckboxTableViewer;
+ private WorkingSetGroup mWorkingSetGroup;
+
+ ImportPage(NewProjectWizardState values) {
+ super("importPage"); //$NON-NLS-1$
+ mValues = values;
+ setTitle("Import Projects");
+ setDescription("Select a directory to search for existing Android projects");
+ mWorkingSetGroup = new WorkingSetGroup();
+ setWorkingSets(new IWorkingSet[0]);
+
+ // Record all projects such that we can ensure that the project names are unique
+ IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+ mExistingProjects = workspaceRoot.getProjects();
+ }
+
+ public void init(IStructuredSelection selection, IWorkbenchPart activePart) {
+ setWorkingSets(WorkingSetHelper.getSelectedWorkingSet(selection, activePart));
+ }
+
+ @SuppressWarnings("unused") // SWT constructors have side effects and aren't unused
+ @Override
+ public void createControl(Composite parent) {
+ Composite container = new Composite(parent, SWT.NULL);
+ setControl(container);
+ container.setLayout(new GridLayout(3, false));
+
+ Label directoryLabel = new Label(container, SWT.NONE);
+ directoryLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+ directoryLabel.setText("Root Directory:");
+
+ mDir = new Text(container, SWT.BORDER);
+ mDir.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+ mDir.addKeyListener(this);
+ mDir.addTraverseListener(this);
+
+ mBrowseButton = new Button(container, SWT.NONE);
+ mBrowseButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+ mBrowseButton.setText("Browse...");
+ mBrowseButton.addSelectionListener(this);
+
+ Label projectsLabel = new Label(container, SWT.NONE);
+ projectsLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
+ projectsLabel.setText("Projects:");
+
+ mTable = new Table(container, SWT.CHECK);
+ mTable.setHeaderVisible(true);
+ mCheckboxTableViewer = new CheckboxTableViewer(mTable);
+
+ TableViewerColumn dirViewerColumn = new TableViewerColumn(mCheckboxTableViewer, SWT.NONE);
+ TableColumn dirColumn = dirViewerColumn.getColumn();
+ dirColumn.setWidth(200);
+ dirColumn.setText("Project to Import");
+ TableViewerColumn nameViewerColumn = new TableViewerColumn(mCheckboxTableViewer, SWT.NONE);
+ TableColumn nameColumn = nameViewerColumn.getColumn();
+ nameColumn.setWidth(200);
+ nameColumn.setText("New Project Name");
+ nameViewerColumn.setEditingSupport(new ProjectNameEditingSupport(mCheckboxTableViewer));
+
+ mTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 4));
+ mTable.setLinesVisible(true);
+ mTable.setHeaderVisible(true);
+ mTable.addSelectionListener(this);
+ mTable.addControlListener(this);
+ mCheckboxTableViewer.setContentProvider(this);
+ mCheckboxTableViewer.setInput(this);
+ mCheckboxTableViewer.addCheckStateListener(this);
+ mCheckboxTableViewer.setLabelProvider(new ProjectCellLabelProvider());
+
+ mSelectAllButton = new Button(container, SWT.NONE);
+ mSelectAllButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+ mSelectAllButton.setText("Select All");
+ mSelectAllButton.addSelectionListener(this);
+
+ mDeselectAllButton = new Button(container, SWT.NONE);
+ mDeselectAllButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+ mDeselectAllButton.setText("Deselect All");
+ mDeselectAllButton.addSelectionListener(this);
+
+ mRefreshButton = new Button(container, SWT.NONE);
+ mRefreshButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+ mRefreshButton.setText("Refresh");
+ mRefreshButton.addSelectionListener(this);
+ new Label(container, SWT.NONE);
+
+ mCopyCheckBox = new Button(container, SWT.CHECK);
+ mCopyCheckBox.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
+ mCopyCheckBox.setText("Copy projects into workspace");
+ mCopyCheckBox.addSelectionListener(this);
+
+ Composite group = mWorkingSetGroup.createControl(container);
+ group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
+
+ updateColumnWidths();
+ }
+
+ private void updateColumnWidths() {
+ Rectangle r = mTable.getClientArea();
+ int availableWidth = r.width;
+ // Add all available size to the first column
+ for (int i = 1; i < mTable.getColumnCount(); i++) {
+ TableColumn column = mTable.getColumn(i);
+ availableWidth -= column.getWidth();
+ }
+ if (availableWidth > 100) {
+ mTable.getColumn(0).setWidth(availableWidth);
+ }
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+ validatePage();
+ }
+
+ private void refresh() {
+ File root = new File(mDir.getText().trim());
+ mProjectPaths = searchForProjects(root);
+ mCheckboxTableViewer.refresh();
+ mCheckboxTableViewer.setAllChecked(true);
+
+ updateValidity();
+ validatePage();
+ }
+
+ private void updateValidity(){
+ List<ImportedProject> selected = new ArrayList<ImportedProject>();
+ List<ImportedProject> disabled = new ArrayList<ImportedProject>();
+ for (ImportedProject project : mProjectPaths) {
+ String projectName = project.getProjectName();
+ boolean invalid = false;
+ for (IProject existingProject : mExistingProjects) {
+ if (projectName.equals(existingProject.getName())) {
+ invalid = true;
+ break;
+ }
+ }
+ if (invalid) {
+ disabled.add(project);
+ } else {
+ selected.add(project);
+ }
+ }
+
+ mValues.importProjects = selected;
+
+ mCheckboxTableViewer.setGrayedElements(disabled.toArray());
+ mCheckboxTableViewer.setCheckedElements(selected.toArray());
+ mCheckboxTableViewer.refresh();
+ mCheckboxTableViewer.getTable().setFocus();
+ }
+
+ private List<ImportedProject> searchForProjects(File dir) {
+ List<ImportedProject> projects = new ArrayList<ImportedProject>();
+ addProjects(dir, projects, dir.getPath().length() + 1);
+ return projects;
+ }
+
+ /** Finds all project directories under the given directory */
+ private void addProjects(File dir, List<ImportedProject> projects, int prefixLength) {
+ if (dir.isDirectory()) {
+ if (LintUtils.isManifestFolder(dir)) {
+ String relative = dir.getPath();
+ if (relative.length() > prefixLength) {
+ relative = relative.substring(prefixLength);
+ }
+ projects.add(new ImportedProject(dir, relative));
+ }
+
+ File[] children = dir.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ addProjects(child, projects, prefixLength);
+ }
+ }
+ }
+ }
+
+ private void validatePage() {
+ IStatus status = null;
+
+ // Validate project name -- unless we're creating a sample, in which case
+ // the user will get a chance to pick the name on the Sample page
+ if (mProjectPaths == null || mProjectPaths.isEmpty()) {
+ status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ "Select a directory to search for existing Android projects");
+ } else if (mValues.importProjects == null || mValues.importProjects.isEmpty()) {
+ status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ "Select at least one project");
+ } else {
+ for (ImportedProject project : mValues.importProjects) {
+ if (mCheckboxTableViewer.getGrayed(project)) {
+ status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ String.format("Cannot import %1$s because the project name is in use",
+ project.getProjectName()));
+ break;
+ } else {
+ status = ProjectNamePage.validateProjectName(project.getProjectName());
+ if (status != null && !status.isOK()) {
+ // Need to insert project name to make it clear which project name
+ // is in violation
+ if (mValues.importProjects.size() > 1) {
+ String message = String.format("%1$s: %2$s",
+ project.getProjectName(), status.getMessage());
+ status = new Status(status.getSeverity(), AdtPlugin.PLUGIN_ID,
+ message);
+ }
+ break;
+ } else {
+ status = null; // Don't leave non null status with isOK() == true
+ }
+ }
+ }
+ }
+
+ // -- update UI & enable finish if there's no error
+ setPageComplete(status == null || status.getSeverity() != IStatus.ERROR);
+ if (status != null) {
+ setMessage(status.getMessage(),
+ status.getSeverity() == IStatus.ERROR
+ ? IMessageProvider.ERROR : IMessageProvider.WARNING);
+ } else {
+ setErrorMessage(null);
+ setMessage(null);
+ }
+ }
+
+ /**
+ * Returns the working sets to which the new project should be added.
+ *
+ * @return the selected working sets to which the new project should be added
+ */
+ private IWorkingSet[] getWorkingSets() {
+ return mWorkingSetGroup.getSelectedWorkingSets();
+ }
+
+ /**
+ * Sets the working sets to which the new project should be added.
+ *
+ * @param workingSets the initial selected working sets
+ */
+ private void setWorkingSets(IWorkingSet[] workingSets) {
+ assert workingSets != null;
+ mWorkingSetGroup.setWorkingSets(workingSets);
+ }
+
+ @Override
+ public IWizardPage getNextPage() {
+ // Sync working set data to the value object, since the WorkingSetGroup
+ // doesn't let us add listeners to do this lazily
+ mValues.workingSets = getWorkingSets();
+
+ return super.getNextPage();
+ }
+
+ // ---- Implements SelectionListener ----
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Object source = e.getSource();
+ if (source == mBrowseButton) {
+ // Choose directory
+ DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.OPEN);
+ String path = mDir.getText().trim();
+ if (path.length() > 0) {
+ dialog.setFilterPath(path);
+ }
+ String file = dialog.open();
+ if (file != null) {
+ mDir.setText(file);
+ refresh();
+ }
+ } else if (source == mSelectAllButton) {
+ mCheckboxTableViewer.setAllChecked(true);
+ mValues.importProjects = mProjectPaths;
+ } else if (source == mDeselectAllButton) {
+ mCheckboxTableViewer.setAllChecked(false);
+ mValues.importProjects = Collections.emptyList();
+ } else if (source == mRefreshButton || source == mDir) {
+ refresh();
+ } else if (source == mCopyCheckBox) {
+ mValues.copyIntoWorkspace = mCopyCheckBox.getSelection();
+ }
+
+ validatePage();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+
+ // ---- KeyListener ----
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if (e.getSource() == mDir) {
+ if (e.keyCode == SWT.CR) {
+ refresh();
+ }
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ }
+
+ // ---- TraverseListener ----
+
+ @Override
+ public void keyTraversed(TraverseEvent e) {
+ // Prevent Return from running through the wizard; return is handled by
+ // key listener to refresh project list instead
+ if (SWT.TRAVERSE_RETURN == e.detail) {
+ e.doit = false;
+ }
+ }
+
+ // ---- Implements IStructuredContentProvider ----
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return mProjectPaths != null ? mProjectPaths.toArray() : new Object[0];
+ }
+
+ // ---- Implements ICheckStateListener ----
+
+ @Override
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ // Try to disable other elements that conflict with this
+ Object[] checked = mCheckboxTableViewer.getCheckedElements();
+ List<ImportedProject> selected = new ArrayList<ImportedProject>(checked.length);
+ for (Object o : checked) {
+ if (!mCheckboxTableViewer.getGrayed(o)) {
+ selected.add((ImportedProject) o);
+ }
+ }
+ mValues.importProjects = selected;
+ validatePage();
+
+ mCheckboxTableViewer.update(event.getElement(), null);
+ }
+
+ // ---- Implements ControlListener ----
+
+ @Override
+ public void controlMoved(ControlEvent e) {
+ }
+
+ @Override
+ public void controlResized(ControlEvent e) {
+ updateColumnWidths();
+ }
+
+ private final class ProjectCellLabelProvider extends CellLabelProvider {
+ @Override
+ public void update(ViewerCell cell) {
+ Object element = cell.getElement();
+ int index = cell.getColumnIndex();
+ ImportedProject project = (ImportedProject) element;
+
+ Display display = mTable.getDisplay();
+ Color fg;
+ if (mCheckboxTableViewer.getGrayed(element)) {
+ fg = display.getSystemColor(SWT.COLOR_DARK_GRAY);
+ } else {
+ fg = display.getSystemColor(SWT.COLOR_LIST_FOREGROUND);
+ }
+ cell.setForeground(fg);
+ cell.setBackground(display.getSystemColor(SWT.COLOR_LIST_BACKGROUND));
+
+ switch (index) {
+ case DIR_COLUMN: {
+ // Directory name
+ cell.setText(project.getRelativePath());
+ return;
+ }
+
+ case NAME_COLUMN: {
+ // New name
+ cell.setText(project.getProjectName());
+ return;
+ }
+ default:
+ assert false : index;
+ }
+ cell.setText("");
+ }
+ }
+
+ /** Editing support for the project name column */
+ private class ProjectNameEditingSupport extends EditingSupport {
+ private ProjectNameEditingSupport(ColumnViewer viewer) {
+ super(viewer);
+ }
+
+ @Override
+ protected void setValue(Object element, Object value) {
+ ImportedProject project = (ImportedProject) element;
+ project.setProjectName(value.toString());
+ mCheckboxTableViewer.update(element, null);
+ updateValidity();
+ validatePage();
+ }
+
+ @Override
+ protected Object getValue(Object element) {
+ ImportedProject project = (ImportedProject) element;
+ return project.getProjectName();
+ }
+
+ @Override
+ protected CellEditor getCellEditor(Object element) {
+ return new TextCellEditor(mTable);
+ }
+
+ @Override
+ protected boolean canEdit(Object element) {
+ return true;
+ }
+ }
+}