package org.openlca.app.wizards.io; import java.io.File; import java.util.ArrayList; import java.util.HashSet; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; 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.Label; import org.eclipse.swt.widgets.Text; import org.openlca.app.M; import org.openlca.app.Preferences; import org.openlca.app.util.Colors; import org.openlca.app.util.UI; /** * Wizard page for file import: the user can select files from directories. */ public class FileImportPage extends WizardPage { private TreeViewer directoryViewer; private HashSet<String> fileExtensions = new HashSet<>(); private File[] selectedFiles; private TableViewer fileViewer; private boolean multiSelection; private File lastDir; private Text directoryText; public FileImportPage(String[] fileExtensions, boolean multi) { super("FileImportPage"); setTitle(M.SelectImportFiles); setDescription(M.FileImportPage_Description); if (fileExtensions != null) { for (String extension : fileExtensions) this.fileExtensions.add(extension.toLowerCase()); } setPageComplete(false); this.multiSelection = multi; lastDir = getLastDir(); } private File getLastDir() { String lastDirPath = Preferences.get(Preferences.LAST_IMPORT_FOLDER); if (lastDirPath == null) return null; File f = new File(lastDirPath); if (f.exists() && f.isDirectory()) return f; return null; } @Override public void createControl(final Composite parent) { // create body final Composite body = new Composite(parent, SWT.NONE); final GridLayout bodyLayout = new GridLayout(1, true); bodyLayout.marginHeight = 10; bodyLayout.marginWidth = 10; bodyLayout.verticalSpacing = 10; body.setLayout(bodyLayout); // create composite final Composite chooseDirectoryComposite = new Composite(body, SWT.NONE); final GridLayout dirLayout = new GridLayout(3, false); dirLayout.marginLeft = 0; dirLayout.marginRight = 0; dirLayout.marginBottom = 0; dirLayout.marginTop = 0; dirLayout.marginHeight = 0; dirLayout.marginWidth = 0; chooseDirectoryComposite.setLayout(dirLayout); chooseDirectoryComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); new Label(chooseDirectoryComposite, SWT.NONE) .setText(M.FromDirectory); createDirectoryText(chooseDirectoryComposite); // create button to open directory dialog final Button chooseDirectoryButton = new Button( chooseDirectoryComposite, SWT.NONE); chooseDirectoryButton.setText(M.ChooseDirectory); chooseDirectoryButton.addSelectionListener(new DirectorySelection()); new Label(body, SWT.SEPARATOR | SWT.HORIZONTAL) .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); // create composite final Composite chooseFileComposite = new Composite(body, SWT.NONE); final GridLayout fileLayout = new GridLayout(2, true); fileLayout.marginLeft = 0; fileLayout.marginRight = 0; fileLayout.marginBottom = 0; fileLayout.marginTop = 0; fileLayout.marginHeight = 0; fileLayout.marginWidth = 0; fileLayout.horizontalSpacing = 10; chooseFileComposite.setLayout(fileLayout); chooseFileComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); // create tree viewer for selecting a sub directory directoryViewer = new TreeViewer(chooseFileComposite, SWT.BORDER | SWT.SINGLE); final GridData gddv = new GridData(SWT.FILL, SWT.FILL, true, true); directoryViewer.getTree().setLayoutData(gddv); directoryViewer.setContentProvider(new DirectoryContentProvider()); directoryViewer.setLabelProvider(new FileLabelProvider()); directoryViewer.addSelectionChangedListener((e) -> { if (!e.getSelection().isEmpty()) { IStructuredSelection selection = (IStructuredSelection) e .getSelection(); fileViewer.setInput(selection.getFirstElement()); } }); // create table viewer to select a file from a selected sub directory fileViewer = new TableViewer(chooseFileComposite, SWT.BORDER | SWT.FULL_SELECTION | (multiSelection ? SWT.MULTI : SWT.SINGLE)); final GridData gdfv = new GridData(SWT.FILL, SWT.FILL, true, true); fileViewer.getTable().setLayoutData(gdfv); fileViewer.setContentProvider(new FileContentProvider()); fileViewer.setLabelProvider(new FileLabelProvider()); fileViewer.addSelectionChangedListener((event) -> { ISelection selection = event.getSelection(); if (!(selection instanceof IStructuredSelection) || selection.isEmpty()) { setPageComplete(false); return; } Object[] files = ((IStructuredSelection) selection).toArray(); selectedFiles = new File[files.length]; for (int i = 0; i < files.length; i++) { selectedFiles[i] = (File) files[i]; } setPageComplete(true); }); setViewerInput(); setControl(body); } private void setViewerInput() { // we need to set the input when the components are already painted to // avoid SWT sizing problems fileViewer.getTable().addPaintListener(new PaintListener() { @Override public void paintControl(PaintEvent e) { if (lastDir != null) { fileViewer.setInput(lastDir); directoryViewer.setInput(lastDir); } fileViewer.getTable().removePaintListener(this); } }); } private void createDirectoryText(Composite composite) { directoryText = new Text(composite, SWT.BORDER); if (lastDir != null) directoryText.setText(lastDir.getAbsolutePath()); directoryText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); directoryText.setEditable(false); directoryText.setBackground(Colors.get(255, 255, 255)); } /** Get the selected files from the page. */ public File[] getFiles() { return selectedFiles; } private class DirectoryContentProvider implements ITreeContentProvider { @Override public void dispose() { } @Override public Object[] getChildren(final Object parentElement) { final ArrayList<File> elements = new ArrayList<>(); if (parentElement instanceof File) { final File file = (File) parentElement; for (final File child : file.listFiles()) { if (child.isDirectory()) { elements.add(child); } } } return elements.toArray(new File[elements.size()]); } @Override public Object[] getElements(final Object inputElement) { final ArrayList<File> elements = new ArrayList<>(); if (inputElement instanceof File) { final File file = (File) inputElement; for (final File child : file.listFiles()) { if (child.isDirectory()) { elements.add(child); } } } return elements.toArray(new File[elements.size()]); } @Override public Object getParent(final Object element) { File parent = null; if (element instanceof File) { final File file = (File) element; if (file.getParentFile() != null && file.getParentFile().isDirectory()) { parent = file; } } return parent; } @Override public boolean hasChildren(final Object element) { boolean hasChildren = false; if (element instanceof File) { final File file = (File) element; int i = 0; final File[] files = file.listFiles(); if (files != null) { while (!hasChildren && i < files.length) { if (files[i].isDirectory()) { hasChildren = true; } else { i++; } } } } return hasChildren; } @Override public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) { } } private class FileContentProvider implements IStructuredContentProvider { @Override public void dispose() { } @Override public Object[] getElements(final Object inputElement) { final ArrayList<File> elements = new ArrayList<>(); if (inputElement instanceof File) { final File file = (File) inputElement; if (file.isDirectory()) { final File[] files = file.listFiles(); if (files != null) { for (final File child : files) { if (child.isFile()) { String extension = child.getName(); while (extension.contains(".")) { extension = extension.substring(extension .indexOf('.') + 1); } extension = extension.toLowerCase(); if (fileExtensions.size() == 0 || fileExtensions.contains(extension)) { elements.add(child); } } } } } } return elements.toArray(new File[elements.size()]); } @Override public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) { } } private class DirectorySelection implements SelectionListener { @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } @Override public void widgetSelected(final SelectionEvent e) { DirectoryDialog dialog = new DirectoryDialog(UI.shell()); if (lastDir != null) dialog.setFilterPath(lastDir.getAbsolutePath()); String directoryPath = dialog.open(); if (directoryPath != null) { lastDir = new File(directoryPath); directoryText.setText(directoryPath); Preferences.set(Preferences.LAST_IMPORT_FOLDER, directoryPath); directoryViewer.setInput(lastDir); fileViewer.setInput(lastDir); } } } }