package org.openlca.app.wizards.io; import java.io.File; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; 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.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.Text; import org.openlca.app.M; import org.openlca.app.Preferences; import org.openlca.app.components.FileChooser; import org.openlca.app.db.Database; import org.openlca.app.db.IDatabaseConfiguration; import org.openlca.app.navigation.NavigationContentProvider; import org.openlca.app.navigation.NavigationLabelProvider; import org.openlca.app.navigation.NavigationSorter; import org.openlca.app.navigation.Navigator; import org.openlca.app.navigation.filters.ModelTypeFilter; import org.openlca.app.util.Colors; import org.openlca.app.util.Controls; import org.openlca.app.util.UI; import org.openlca.core.model.ModelType; import org.openlca.core.model.descriptors.BaseDescriptor; public class ModelSelectionPage extends WizardPage { private ModelType[] types; private File exportDestination; private List<BaseDescriptor> selectedComponents = new ArrayList<>(); private CheckboxTreeViewer viewer; private boolean targetIsDir; private String fileExtension; public static ModelSelectionPage forDirectory(ModelType... types) { ModelSelectionPage page = new ModelSelectionPage(types); page.targetIsDir = true; return page; } /** * For the file extension please use only the extension, e.g. zip instead of * *.zip * * @param extension * @param types * @return */ public static ModelSelectionPage forFile(String extension, ModelType... types) { ModelSelectionPage page = new ModelSelectionPage(types); page.targetIsDir = false; page.fileExtension = extension; return page; } private ModelSelectionPage(ModelType... types) { super(ModelSelectionPage.class.getCanonicalName()); this.types = types; setPageComplete(false); createTexts(); } public File getExportDestination() { return exportDestination; } public List<BaseDescriptor> getSelectedModels() { return selectedComponents; } private void createTexts() { // TODO: change labels to 'Select data sets etc.' String typeName = getTypeName(); String title = M.bind(M.Select, typeName); setTitle(title); String descr = M.SelectObjectPage_Description; descr = M.bind(descr, typeName); setDescription(descr); } // TODO: this method can be removed if the labels are a bit more generic private String getTypeName() { if (types == null || types.length != 1) return M.DataSets; ModelType type = types[0]; switch (type) { case PROCESS: return M.Processes; case IMPACT_METHOD: return M.ImpactAssessmentMethods; case FLOW: return M.Flows; case FLOW_PROPERTY: return M.FlowProperties; case UNIT_GROUP: return M.UnitGroups; case ACTOR: return M.Actors; case SOURCE: return M.Sources; case PRODUCT_SYSTEM: return M.ProductSystems; default: return "unknown"; } } public void checkCompletion() { setPageComplete(exportDestination != null && selectedComponents.size() > 0); } @Override public void createControl(final Composite parent) { Composite body = new Composite(parent, SWT.NULL); GridLayout bodyLayout = new GridLayout(1, true); bodyLayout.marginHeight = 10; bodyLayout.marginWidth = 10; bodyLayout.verticalSpacing = 10; body.setLayout(bodyLayout); createChooseTargetComposite(body); Composite viewerComposite = createViewerComposite(body); createViewer(viewerComposite); setControl(body); checkCompletion(); } private void createChooseTargetComposite(final Composite body) { Composite composite = new Composite(body, SWT.NONE); GridLayout layout = UI.gridLayout(composite, 3); layout.marginHeight = 0; layout.marginWidth = 5; UI.gridData(composite, true, false); String label = targetIsDir ? M.ToDirectory : M.ToFile; new Label(composite, SWT.NONE).setText(label); Text text = createTargetText(composite); text.setEditable(false); text.setBackground(Colors.white()); Button button = new Button(composite, SWT.NONE); button.setText(M.Browse); Controls.onSelect(button, (e) -> selectTarget(text)); } private Text createTargetText(Composite composite) { Text text = new Text(composite, SWT.BORDER); UI.gridData(text, true, false); String lastDir = Preferences.get(Preferences.LAST_EXPORT_FOLDER); if (lastDir == null || !new File(lastDir).exists()) return text; String path = lastDir; if (!targetIsDir) path += File.separator + defaultName(); text.setText(path); exportDestination = new File(path); return text; } private String defaultName() { return Database.get().getName() + "." + fileExtension; } private void selectTarget(Text text) { String dir = Preferences.get(Preferences.LAST_EXPORT_FOLDER); if (targetIsDir) exportDestination = FileChooser.forExport( FileChooser.DIRECTORY_DIALOG, dir); else exportDestination = FileChooser.forExport("*." + fileExtension, defaultName(), dir); if (exportDestination == null) return; String path = exportDestination.getAbsolutePath(); text.setText(path); if (!targetIsDir) path = exportDestination.getParentFile().getAbsolutePath(); Preferences.set(Preferences.LAST_EXPORT_FOLDER, path); checkCompletion(); } private Composite createViewerComposite(final Composite body) { Composite composite = new Composite(body, SWT.NONE); GridLayout layout = new GridLayout(2, false); layout.marginLeft = 0; layout.marginRight = 0; layout.marginBottom = 0; layout.marginTop = 0; layout.marginHeight = 0; layout.marginWidth = 0; composite.setLayout(layout); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); return composite; } private void createViewer(Composite composite) { viewer = new CheckboxTreeViewer(composite, SWT.VIRTUAL | SWT.MULTI | SWT.BORDER); viewer.setUseHashlookup(true); viewer.getTree().setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, true)); viewer.setContentProvider(new NavigationContentProvider()); viewer.setLabelProvider(new NavigationLabelProvider(false)); viewer.setSorter(new NavigationSorter()); viewer.addFilter(new ModelTypeFilter(types)); viewer.addCheckStateListener(new ModelSelectionState(this, viewer)); registerInputHandler(composite); ColumnViewerToolTipSupport.enableFor(viewer); } // We want to avoid a resizing of the import dialog when the user flips to // this page. Thus, we set the input of the tree viewer after receiving the // first paint event. private void registerInputHandler(Composite composite) { composite.addPaintListener(new PaintListener() { private boolean init = false; @Override public void paintControl(PaintEvent e) { if (init) { composite.removePaintListener(this); return; } init = true; setInitialInput(); } }); } private void setInitialInput() { if (types != null && types.length == 1) viewer.setInput(Navigator.findElement(types[0])); else { IDatabaseConfiguration config = Database.getActiveConfiguration(); viewer.setInput(Navigator.findElement(config)); } } }