blob: f67239e65bb4f4adfe49583cf82ccfaf73d32016 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 Red Hat Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Mickael Istria (Red Hat Inc.) - initial API and implementation
******************************************************************************/
package org.eclipse.ui.internal.wizards.datatransfer;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IPageChangeProvider;
import org.eclipse.jface.dialogs.IPageChangedListener;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.PageChangedEvent;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
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.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.wizards.datatransfer.ProjectConfigurator;
public class ImportProposalsWizardPage extends WizardPage implements IPageChangedListener {
private CheckboxTreeViewer tree;
private Set<File> alreadyExistingProjects;
private Set<File> notAlreadyExistingProjects;
private Button recurseInSelectedProjectsCheckbox;
private EasymportJob currentJob;
private Label selectionSummary;
private class FolderForProjectsLabelProvider extends LabelProvider implements IColorProvider {
@Override
public String getText(Object o) {
if (alreadyExistingProjects.contains(o)) {
return super.getText(o)+ " (" + Messages.alreadyImportedAsProject_title + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
return super.getText(o);
}
@Override
public Color getBackground(Object o) {
return null;
}
@Override
public Color getForeground(Object o) {
if (alreadyExistingProjects.contains(o)) {
return Display.getDefault().getSystemColor(SWT.COLOR_GRAY);
}
return null;
}
}
public ImportProposalsWizardPage(EasymportWizard wizard) {
super(ImportProposalsWizardPage.class.getName());
setWizard(wizard);
}
@Override
public void createControl(Composite parent) {
setTitle(Messages.preliminaryDetection_Title);
setDescription(Messages.preliminaryDetection_Description);
if (getContainer() instanceof IPageChangeProvider) {
((IPageChangeProvider)getContainer()).addPageChangedListener(this);
}
Composite res = new Composite(parent, SWT.NONE);
res.setLayout(new GridLayout(2, false));
selectionSummary = new Label(res, SWT.NONE);
selectionSummary.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false, 2, 1));
tree = new CheckboxTreeViewer(res, SWT.BORDER);
tree.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
tree.setContentProvider(new ITreeContentProvider() {
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
@Override
public Object[] getElements(Object inputElement) {
Map<File, ?> potentialProjects = (Map<File, ?>)inputElement;
return potentialProjects.keySet().toArray(new File[potentialProjects.size()]);
}
@Override
public Object[] getChildren(Object parentElement) {
return null;
}
@Override
public Object getParent(Object element) {
return null;
}
@Override
public boolean hasChildren(Object element) {
return false;
}
});
tree.setLabelProvider(new LabelProvider() {
@Override
public String getText(Object o) {
return ((File)o).getAbsolutePath();
}
});
tree.setComparator(new ViewerComparator() {
@Override
public int compare(Viewer v, Object o1, Object o2) {
return ((File)o1).getAbsolutePath().compareTo(((File)o2).getAbsolutePath());
}
});
tree.addCheckStateListener(new ICheckStateListener() {
@Override
public void checkStateChanged(CheckStateChangedEvent event) {
if (ImportProposalsWizardPage.this.alreadyExistingProjects.contains(event.getElement())) {
tree.setChecked(event.getElement(), false);
} else {
selectionChanged();
}
}
});
tree.setLabelProvider(new FolderForProjectsLabelProvider());
Composite selectionButtonsGroup = new Composite(res, SWT.NONE);
selectionButtonsGroup.setLayout(new GridLayout(1, false));
selectionButtonsGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
Button selectAllButton = new Button(selectionButtonsGroup, SWT.PUSH);
selectAllButton.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, false, false));
selectAllButton.setText(DataTransferMessages.DataTransfer_selectAll);
selectAllButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
tree.setCheckedElements(ImportProposalsWizardPage.this.notAlreadyExistingProjects.toArray());
selectionChanged();
}
});
Button deselectAllButton = new Button(selectionButtonsGroup, SWT.PUSH);
deselectAllButton.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, false, false));
deselectAllButton.setText(DataTransferMessages.DataTransfer_deselectAll);
deselectAllButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
tree.setCheckedElements(new Object[0]);
selectionChanged();
}
});
recurseInSelectedProjectsCheckbox = new Button(res, SWT.CHECK);
recurseInSelectedProjectsCheckbox.setText("Use additional analysis after import to detect nested project under selected projects\n(BEWARE: this may create new projects in your workspace without ability to review it first!)");
recurseInSelectedProjectsCheckbox.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, false, false, 2, 1));
recurseInSelectedProjectsCheckbox.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
getWizard().getImportJob().setDetectNestedProjects(recurseInSelectedProjectsCheckbox.getSelection());
}
});
setPageComplete(true);
setControl(res);
}
@Override
public boolean isPageComplete() {
return getWizard().getImportJob() != null &&
getWizard().getImportJob().getDirectoriesToImport() != null &&
!getWizard().getImportJob().getDirectoriesToImport().isEmpty();
}
@Override
public void setWizard(IWizard easymportWizard) {
Assert.isTrue(easymportWizard instanceof EasymportWizard);
super.setWizard(easymportWizard);
}
public EasymportWizard getWizard() {
return (EasymportWizard)super.getWizard();
}
private void updateTreeContent() {
try {
getContainer().run(false, false, new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
final Map<File, List<ProjectConfigurator>> potentialProjects = getWizard().getImportJob().getImportProposals(monitor);
if (potentialProjects.size() == 0) {
MessageDialog.openInformation(getShell(),
Messages.didntFindImportProposals_title,
NLS.bind(Messages.didntFindImportProposals_message, recurseInSelectedProjectsCheckbox.getText()));
} else {
// if some projects were detected thanks to metadata, assume projects has necessary metadata for good import
// and skip additional nested project detection.
getWizard().getImportJob().setDetectNestedProjects(false);
}
recurseInSelectedProjectsCheckbox.setSelection(getWizard().getImportJob().isDetectNestedProjects());
if (!potentialProjects.containsKey(getWizard().getImportJob().getRoot())) {
potentialProjects.put(getWizard().getImportJob().getRoot(), Collections.EMPTY_LIST);
// force nested detection when the import didn't manage to do something
getWizard().getImportJob().setDetectNestedProjects(true);
}
ImportProposalsWizardPage.this.notAlreadyExistingProjects = new HashSet<File>(potentialProjects.keySet());
ImportProposalsWizardPage.this.alreadyExistingProjects = new HashSet<File>();
for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
ImportProposalsWizardPage.this.notAlreadyExistingProjects.remove(project.getLocation().toFile());
ImportProposalsWizardPage.this.alreadyExistingProjects.add(project.getLocation().toFile());
}
tree.setInput(potentialProjects);
tree.setCheckedElements(ImportProposalsWizardPage.this.notAlreadyExistingProjects.toArray());
}
});
selectionChanged();
} catch (InterruptedException ex) {
tree.setInput(Collections.EMPTY_MAP);
getWizard().getImportJob().resetProposals();
} catch (InvocationTargetException ex) {
MessageDialog.openError(getShell(), "Sorry...", "An internal error occured. Please see log file for details.");
Activator.getDefault().getLog().log(new Status(IStatus.ERROR,
Activator.getDefault().getBundle().getSymbolicName(),
ex.getMessage(),
ex));
}
}
@Override
public void pageChanged(PageChangedEvent event) {
if (event.getSelectedPage() == this) {
EasymportJob newJob = getWizard().getImportJob();
if (newJob != this.currentJob) {
this.currentJob = newJob;
recurseInSelectedProjectsCheckbox.setSelection(getWizard().getImportJob().isDetectNestedProjects());
updateTreeContent();
}
}
}
@Override
public void dispose() {
if (getContainer() instanceof IPageChangeProvider) {
((IPageChangeProvider)getContainer()).removePageChangedListener(this);
}
super.dispose();
}
private void selectionChanged() {
Object[] selected = tree.getCheckedElements();
EasymportJob importJob = getWizard().getImportJob();
Set<File> excludedDirectories = new HashSet(((Map<File, ?>)this.tree.getInput()).keySet());
Set<File> selectedProjects = new HashSet<File>();
for (Object item : selected) {
File directory = (File)item;
excludedDirectories.remove(directory);
selectedProjects.add(directory);
}
importJob.setDirectoriesToImport(selectedProjects);
importJob.setExcludedDirectories(excludedDirectories);
selectionSummary.setText(NLS.bind(Messages.selectionSummary, importJob.getImportProposals(null).size(), importJob.getDirectoriesToImport().size()));
setPageComplete(isPageComplete());
}
}