/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.modeling.ui.typicals; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashSet; import java.util.Set; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.resource.ResourceManager; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ISelection; 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.TableViewer; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.simantics.Simantics; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.NamedResource; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.modeling.ModelingResources; import org.simantics.modeling.typicals.AvailableSynchronizationRules; import org.simantics.modeling.ui.Activator; import org.simantics.utils.datastructures.Arrays; import org.simantics.utils.strings.AlphanumComparator; /** * @author Antti Villberg */ public class RuleChooserDialog extends Dialog { public static class RuleResult { public final Set selectedRules; public final boolean logging; RuleResult(Set selectedRules, boolean logging) { this.selectedRules = selectedRules; this.logging = logging; } } private static final String DIALOG = "RuleChooserDialog"; //$NON-NLS-1$ private static final String LAST_SELECTION = "LastSelection"; //$NON-NLS-1$ private final NamedResource[] rules; private final String title; private final String description; private Collection selectedRules; private boolean loggingEnabled = false; private TableViewer viewer; private Button logEnabled; private IDialogSettings dialogBoundsSettings; private ResourceManager resourceManager; private final Comparator sorter = new Comparator() { @Override public int compare(NamedResource nr1, NamedResource nr2) { return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(nr1.getName(), nr2.getName()); } }; public RuleChooserDialog(Shell parent, String description, Collection rules) { super(parent); this.rules = rules.toArray(new NamedResource[rules.size()]); java.util.Arrays.sort(this.rules, sorter); this.title = "Choose Synchronization Rules"; this.description = description; IDialogSettings settings = Activator.getDefault().getDialogSettings(); dialogBoundsSettings = settings.getSection(DIALOG); if (dialogBoundsSettings == null) dialogBoundsSettings = settings.addNewSection(DIALOG); } @Override protected IDialogSettings getDialogBoundsSettings() { return dialogBoundsSettings; } @Override protected void configureShell(Shell newShell) { if (title != null) { newShell.setText(title); } else { newShell.setText("Choose Action"); } super.configureShell(newShell); } @Override protected int getShellStyle() { return super.getShellStyle() | SWT.RESIZE; } @Override protected Point getInitialSize() { Point defaultSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true); Point result = super.getInitialSize(); if (defaultSize.equals(result)) return new Point(500, 500); return result; } @Override protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent); this.resourceManager = new LocalResourceManager(JFaceResources.getResources()); composite.addListener(SWT.Dispose, new Listener() { @Override public void handleEvent(Event event) { resourceManager.dispose(); resourceManager = null; } }); if (description != null) { Text label = new Text(composite, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP); label.setBackground(composite.getBackground()); label.setText(description); label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); } viewer = new TableViewer(composite, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER | SWT.SINGLE | SWT.CHECK); viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); viewer.setContentProvider(new ArrayContentProvider()); viewer.setLabelProvider(new RuleLabelProvider()); viewer.setInput(rules); viewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { RuleChooserDialog.this.selectionChanged(event.getSelection()); } }); logEnabled = new Button(composite, SWT.CHECK); logEnabled.setText("Verbose synchronization logging"); if (rules.length > 0) { viewer.setSelection(new StructuredSelection(rules[0]), true); viewer.getTable().setFocus(); } String[] lastChecked = dialogBoundsSettings.getArray(LAST_SELECTION); if(lastChecked != null) { for(TableItem item : viewer.getTable().getItems()) { NamedResource nr = (NamedResource)item.getData(); if(Arrays.contains(lastChecked, nr.getName())) item.setChecked(true); } } applyDialogFont(composite); return composite; } private void selectionChanged(ISelection s) { Button ok = getButton(IDialogConstants.OK_ID); IStructuredSelection iss = (IStructuredSelection) s; if (iss == null || iss.isEmpty()) { if (ok != null) ok.setEnabled(false); return; } if (ok != null) ok.setEnabled(true); return; } @Override protected void okPressed() { ArrayList names = new ArrayList(); selectedRules = new ArrayList(); for(TableItem item : viewer.getTable().getItems()) { if(item.getChecked()) { NamedResource nr = (NamedResource)item.getData(); selectedRules.add(nr); names.add(nr.getName()); } } loggingEnabled = logEnabled.getSelection(); dialogBoundsSettings.put(LAST_SELECTION, names.toArray(new String[names.size()])); super.okPressed(); } public Collection getSelectedRules() { return selectedRules; } public boolean isLoggingEnabled() { return loggingEnabled; } class RuleLabelProvider extends LabelProvider { @Override public Image getImage(Object element) { return null; } @Override public String getText(Object element) { NamedResource nr = (NamedResource) element; return nr.getName(); } } public static RuleResult choose(Shell shell, String description, final Resource[] input) throws DatabaseException { final Collection rules = new HashSet(); final Collection alwaysEnabledRules = new HashSet(); Simantics.getSession().syncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { ModelingResources MOD = ModelingResources.getInstance(graph); for(Resource r : input) { Collection nrs = graph.syncRequest(new AvailableSynchronizationRules(r)); for (NamedResource nr : nrs) { boolean alwaysEnabled = Boolean.TRUE.equals( graph.getPossibleRelatedValue(nr.getResource(), MOD.TypicalSynchronizationRule_alwaysEnabled, Bindings.BOOLEAN) ); if (alwaysEnabled) alwaysEnabledRules.add(nr.getResource()); else rules.add(nr); } } } }); description += "\n\nChecked rules will be applied in addition to default rules."; RuleChooserDialog dialog = new RuleChooserDialog(shell, description, rules); int ret = dialog.open(); if (ret != Window.OK) return null; Collection selectedRules = dialog.getSelectedRules(); Set selectedRuleResources = new HashSet(); for(NamedResource nr : selectedRules) selectedRuleResources.add(nr.getResource()); selectedRuleResources.addAll(alwaysEnabledRules); return new RuleResult(selectedRuleResources, dialog.isLoggingEnabled()); } }