package org.openlca.app.components; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.action.Action; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.FormDialog; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; import org.openlca.app.M; import org.openlca.app.navigation.INavigationElement; import org.openlca.app.navigation.ModelElement; import org.openlca.app.navigation.ModelTextFilter; import org.openlca.app.navigation.NavigationTree; import org.openlca.app.rcp.images.Icon; import org.openlca.app.util.Actions; import org.openlca.app.util.UI; import org.openlca.core.model.ModelType; import org.openlca.core.model.descriptors.BaseDescriptor; public class ModelSelectionDialog extends FormDialog { private final ModelType modelType; private boolean multiSelection = false; private TreeViewer viewer; private Text filterText; private BaseDescriptor[] selection; public static BaseDescriptor select(ModelType type) { ModelSelectionDialog dialog = new ModelSelectionDialog(UI.shell(), type); if (dialog.open() == OK) { BaseDescriptor[] selection = dialog.getSelection(); if (selection == null || selection.length == 0) return null; return selection[0]; } return null; } public static BaseDescriptor[] multiSelect(ModelType type) { ModelSelectionDialog dialog = new ModelSelectionDialog(UI.shell(), type); dialog.multiSelection = true; if (dialog.open() == OK) return dialog.getSelection(); return null; } private ModelSelectionDialog(Shell parentShell, ModelType modelType) { super(parentShell); this.modelType = modelType; setBlockOnOpen(true); } @Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, false); getButton(IDialogConstants.OK_ID).setEnabled(false); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, true); } @Override protected void createFormContent(IManagedForm form) { FormToolkit tk = form.getToolkit(); UI.formHeader(form, getTitle()); Composite body = UI.formBody(form.getForm(), tk); UI.gridLayout(body, 1); Label filterLabel = UI.formLabel(body, form.getToolkit(), M.Filter); filterLabel.setFont(UI.boldFont()); filterText = UI.formText(body, SWT.SEARCH); Section section = UI.section(body, tk, M.Content); addSectionActions(section); UI.gridData(section, true, true); Composite composite = UI.sectionClient(section, tk); UI.gridLayout(composite, 1); createViewer(composite); } private String getTitle() { if (modelType == null) return "unknown?"; switch (modelType) { case ACTOR: return multiSelection ? M.Actors : M.Actor; case FLOW: return multiSelection ? M.Flows : M.Flow; case FLOW_PROPERTY: return multiSelection ? M.FlowProperties : M.FlowProperty; case IMPACT_METHOD: return multiSelection ? M.ImpactAssessmentMethods : M.ImpactAssessmentMethod; case PROCESS: return multiSelection ? M.Processes : M.Process; case PRODUCT_SYSTEM: return multiSelection ? M.ProductSystems : M.ProductSystem; case PROJECT: return multiSelection ? M.Projects : M.Project; case SOCIAL_INDICATOR: return multiSelection ? M.SocialIndicators : M.SocialIndicator; case SOURCE: return multiSelection ? M.Sources : M.Source; case UNIT_GROUP: return multiSelection ? M.UnitGroups : M.UnitGroup; default: return "unknown?"; } } private void createViewer(Composite composite) { if (multiSelection) viewer = NavigationTree.forMultiSelection(composite, modelType); else viewer = NavigationTree.forSingleSelection(composite, modelType); ModelTextFilter filter = new ModelTextFilter(filterText, viewer); viewer.setFilters(new ViewerFilter[] { filter }); UI.gridData(viewer.getTree(), true, true); viewer.addSelectionChangedListener(new SelectionChangedListener()); viewer.addDoubleClickListener(new DoubleClickListener()); } @Override protected Point getInitialSize() { int width = 600; int height = 600; Rectangle shellBounds = getShell().getDisplay().getBounds(); int shellWidth = shellBounds.x; int shellHeight = shellBounds.y; if (shellWidth > 0 && shellWidth < width) width = shellWidth; if (shellHeight > 0 && shellHeight < height) height = shellHeight; return new Point(width, height); } private void addSectionActions(Section section) { Action expand = Actions.create( M.ExpandAll, Icon.EXPAND.descriptor(), () -> viewer.expandAll()); Action collapse = Actions.create( M.CollapseAll, Icon.COLLAPSE.descriptor(), () -> viewer.collapseAll()); Actions.bind(section, expand, collapse); } @Override protected Point getInitialLocation(Point initialSize) { Point loc = super.getInitialLocation(initialSize); int marginTop = (getParentShell().getSize().y - initialSize.y) / 3; if (marginTop < 0) marginTop = 0; return new Point(loc.x, loc.y + marginTop); } private BaseDescriptor[] getSelection() { return selection; } private boolean matches(ModelElement element) { return element.getContent().getName().toLowerCase() .contains(filterText.getText().toLowerCase()); } private class SelectionChangedListener implements ISelectionChangedListener { @Override public void selectionChanged(SelectionChangedEvent event) { if (event.getSelection() != null && !event.getSelection().isEmpty()) { IStructuredSelection s = (IStructuredSelection) event .getSelection(); List<BaseDescriptor> currentSelection = new ArrayList<>(); for (Object selected : s.toArray()) currentSelection .addAll(getSelection( (INavigationElement<?>) selected)); selection = currentSelection .toArray(new BaseDescriptor[currentSelection.size()]); } getButton(IDialogConstants.OK_ID).setEnabled( selection != null && selection.length > 0); } } private List<BaseDescriptor> getSelection(INavigationElement<?> element) { List<BaseDescriptor> currentSelection = new ArrayList<>(); if (element instanceof ModelElement) { ModelElement modelElement = (ModelElement) element; if (matches(modelElement)) currentSelection.add(modelElement.getContent()); } else for (INavigationElement<?> child : element.getChildren()) currentSelection.addAll(getSelection(child)); return currentSelection; } private class DoubleClickListener implements IDoubleClickListener { @Override public void doubleClick(DoubleClickEvent event) { IStructuredSelection currentSelection = (IStructuredSelection) event .getSelection(); if (currentSelection.getFirstElement() instanceof ModelElement) { ModelElement element = (ModelElement) currentSelection .getFirstElement(); BaseDescriptor modelComponent = element.getContent(); selection = new BaseDescriptor[] { modelComponent }; okPressed(); } } } }