blob: 6ed8d796ac2961b326fd1a62a7cd4c14062ea03e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014 Hussein Mhanna
*
* 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:
* Hussein Mhanna - initial API and implementation
******************************************************************************/
package org.eclipse.rmf.reqif10.csv.importer.ui.wizards.pages;
import java.io.File;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.model.BaseWorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
/**
*
* @author Hussein MHANNA
*
*/
public class CSVImportWizardPage extends WizardPage {
/**
* The reqif file extension
*/
private static final String REQIF_EXTENSION = "reqif";
/**
* The reqif file extension
*/
private static final String CSV_EXTENSION = "csv";
/**
*
*/
private static final String[] CSV_SEPARATOR_ARRAY = new String[] { ",",
";", ":", ".", "\t", "|", "^" };
/**
* The selected path to the file
*/
private String selectedFilePath = "";
/**
* The csv separator
*/
private String separator = CSV_SEPARATOR_ARRAY[0];
/**
* Indicate if the csv contains a header
*/
private boolean containsHeader;
/**
* The selected path to the file
*/
private IFile selectedDestinationFile;
/**
* The constructor
*/
public CSVImportWizardPage() {
super("Import requirements from CSV");
setTitle("Import requirements from CSV");
setDescription("Requirements CSV File Import Wizard");
}
/**
* {@inheritDoc}
*/
@Override
public void createControl(final Composite parent) {
final Composite mainComposite = new Composite(parent, SWT.NONE);
mainComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL,
true, true));
final GridLayout gridLayout = new GridLayout();
mainComposite.setLayout(gridLayout);
createFileSelectionGroup(mainComposite);
createConfigurationGroup(mainComposite);
createReqIFFileSelectionComposite(mainComposite);
validatePage();
setControl(mainComposite);
}
/**
* Create the file selection group.
*
* @param parent
* : The parent composite
*/
protected Group createFileSelectionGroup(final Composite parent) {
final Group group = createGroup(parent, "File Selection");
createLabel(group, "File :");
final Text text = createText(group);
text.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
selectedFilePath = text.getText();
validatePage();
}
});
final Button button = createButton(group, "Browse");
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
final String filePath = browseForFile();
if ((filePath != null) && !filePath.isEmpty()) {
text.setText(filePath);
}
}
});
return group;
}
/**
* Create the configuration group.
*
* @param parent
* : The parent composite
*/
protected Group createConfigurationGroup(final Composite parent) {
final Group group = createGroup(parent, "Configuration");
createLabel(group, "Separator character");
ComboViewer comboViewer = new ComboViewer(group);
comboViewer.setContentProvider(new ArrayContentProvider());
comboViewer.setLabelProvider(new LabelProvider());
comboViewer.setInput(CSV_SEPARATOR_ARRAY);
comboViewer.setSelection(new StructuredSelection(separator));
comboViewer
.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
separator = ((IStructuredSelection) event
.getSelection()).getFirstElement().toString();
}
});
comboViewer.getCombo().setLayoutData(
new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
final Button headerButton = new Button(group, SWT.CHECK);
headerButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,
3, 1));
headerButton.setText("The csv file contains a header");
headerButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
containsHeader = headerButton.getSelection();
}
});
return group;
}
/**
* Create the file destination selection group.
*
* @param parent
* : The parent composite
*/
protected Group createFileDestinationSelectionGroup(final Composite parent) {
final Group group = createGroup(parent, "ReqIF File destination");
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
createReqIFFileSelectionComposite(group);
return group;
}
/**
* Create a {@link Group}
*
* @param parent
* : The parent composite
* @param groupText
* : The group text
* @return The created {@link Group}
*/
private Group createGroup(final Composite parent, String groupText) {
Group group = new Group(parent, SWT.NONE);
group.setText(groupText);
group.setLayout(new GridLayout(3, false));
group.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
return group;
}
/**
* Create a {@link Label}
*
* @param parent
* : The parent composite
* @param labelText
* : The label text
* @return The created {@link Label}
*/
protected Label createLabel(final Composite parent, String labelText) {
final Label label = new Label(parent, SWT.NONE);
label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false,
1, 1));
label.setText(labelText);
return label;
}
/**
* Create a {@link Text}
*
* @param parent
* : The parent composite
* @return The created {@link Text}
*/
protected Text createText(final Composite parent) {
Text text = new Text(parent, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
return text;
}
/**
* Create a button with the text "Browse..."
*
* @param parent
* : The parent composite
* @param buttonText
* : The button text
* @return The created button
*/
protected Button createButton(final Composite parent, String buttonText) {
final Button button = new Button(parent, SWT.NONE);
button.setText(buttonText);
return button;
}
/**
* Create the file selection composite
*
* @param parent
* : The parent composite
*/
protected void createReqIFFileSelectionComposite(Composite parent) {
Group group = createGroup(parent, "Destination ReqIF File");
group.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true,
true));
TreeViewer treeViewer = new TreeViewer(group);
treeViewer.getTree().setLayoutData(
new GridData(GridData.FILL, GridData.FILL, true, true));
treeViewer.setContentProvider(new BaseWorkbenchContentProvider());
treeViewer.setLabelProvider(new WorkbenchLabelProvider());
ViewerFilter reqifFilter = new ViewerFilter() {
@Override
public boolean select(Viewer viewer, Object parentElement,
Object element) {
if (element instanceof IFile) {
return isReqIFFile((IFile) element);
}
return true;
}
};
treeViewer.setFilters(new ViewerFilter[] { reqifFilter });
treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
IFile file = null;
IStructuredSelection selection = (IStructuredSelection) event
.getSelection();
if (false == selection.isEmpty()) {
Object object = selection.getFirstElement();
if (object instanceof IFile && isReqIFFile((IFile) object)) {
file = (IFile) object;
}
}
selectedDestinationFile = file;
validatePage();
}
});
treeViewer.setInput(ResourcesPlugin.getWorkspace().getRoot());
}
/**
* Return whether a file is an reqif file
*
* @param file
* : The file
* @return <code>true</code> if the file extsntion is
* {@link #REQIF_EXTENSION} and <code>false</code> otherwise
*/
protected boolean isReqIFFile(IFile file) {
return file.getFileExtension().equals(REQIF_EXTENSION);
}
/**
* Browse for a file
*
* @return The selected path if any and an empty
*/
protected String browseForFile() {
final FileDialog dialog = createFileDialog();
final String path = dialog.open();
return path == null ? "" : path;
}
/**
* Create and return {@link FileDialog}
*
* @return The created {@link FileDialog}
*/
protected FileDialog createFileDialog() {
final FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
dialog.setFilterExtensions(new String[] { "*." + CSV_EXTENSION });
return dialog;
}
/**
* Update the status of the page, if it is complete or not.
*/
protected boolean validatePage() {
boolean valid = true;
if (selectedFilePath.isEmpty()) {
setFieldEmptyErrorMessage();
valid = false;
} else if (false == checkFileExtension(selectedFilePath)) {
setExtensionErrorMessage();
valid = false;
} else if (false == isFileExist(selectedFilePath)) {
setNoFileErrorMessage(selectedFilePath);
valid = false;
} else if (selectedDestinationFile == null) {
setSelectedReqIFDestinationFileEmptyErrorMessage();
valid = false;
}
if (valid) {
setPageComplete(true);
setMessage(null);
setErrorMessage(null);
}
return valid;
}
/**
* Check if the extension file is compatible.
*
* @param path
* : The path
* @return <code>true</code> if the file extension is compatible and
* <code>false</code> otherwise
*/
protected boolean checkFileExtension(final String path) {
return path.endsWith("."+CSV_EXTENSION);
}
/**
* Check if the given file path is valid.
*
* @param filePath
* : The path
* @return <code>true</code> if the path is valid (exist on the disk) and
* <code>false</code> otherwise
*/
protected boolean isFileExist(final String filePath) {
return new File(filePath).exists();
}
/**
* Set the error message indicating that the text field is empty
*/
protected void setFieldEmptyErrorMessage() {
setMessage(null);
setErrorMessage(" Please select a csv file to import");
setPageComplete(false);
}
/**
* Set the error message indicating that the file must end with .csv
*/
protected void setExtensionErrorMessage() {
setMessage(null);
setErrorMessage("The file name must end with .csv");
setPageComplete(false);
}
/**
* Set the error message indicating that the file doesn't exist
*
* @param fileName
* : The file name
*/
protected void setNoFileErrorMessage(final String fileName) {
setMessage(null);
setErrorMessage("The file " + fileName + "doesn't exists");
setPageComplete(false);
}
/**
* Set the error message indicating that not selected reqif destination file
* selected
*/
protected void setSelectedReqIFDestinationFileEmptyErrorMessage() {
setMessage(null);
setErrorMessage(" Please select the destination ReqIF file (*.reqif)");
setPageComplete(false);
}
/**
* Get the selected file path.
*
* @return the selected file path
*/
public String getSelectedFilePath() {
return selectedFilePath;
}
/**
* Return the separator
*
* @return The separator
*/
public char getSeparator() {
return separator.charAt(0);
}
/**
* Return the selected destination file
*
* @return The selected destination file
*/
public IFile getSelectedDestinationFile() {
return selectedDestinationFile;
}
/**
* Return whether the csv file contains a header
*
* @return <code>true</code> if the csv file contains a header and
* <code>false</code> otherwise
*/
public boolean isContainsHeader() {
return containsHeader;
}
}