]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/typicals/RuleChooserDialog.java
Red background color & tooltip for invalid derived property expression
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / typicals / RuleChooserDialog.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.modeling.ui.typicals;
13
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Comparator;
17 import java.util.HashSet;
18 import java.util.Set;
19
20 import org.eclipse.jface.dialogs.Dialog;
21 import org.eclipse.jface.dialogs.IDialogConstants;
22 import org.eclipse.jface.dialogs.IDialogSettings;
23 import org.eclipse.jface.resource.JFaceResources;
24 import org.eclipse.jface.resource.LocalResourceManager;
25 import org.eclipse.jface.resource.ResourceManager;
26 import org.eclipse.jface.viewers.ArrayContentProvider;
27 import org.eclipse.jface.viewers.ISelection;
28 import org.eclipse.jface.viewers.ISelectionChangedListener;
29 import org.eclipse.jface.viewers.IStructuredSelection;
30 import org.eclipse.jface.viewers.LabelProvider;
31 import org.eclipse.jface.viewers.SelectionChangedEvent;
32 import org.eclipse.jface.viewers.StructuredSelection;
33 import org.eclipse.jface.viewers.TableViewer;
34 import org.eclipse.jface.window.Window;
35 import org.eclipse.swt.SWT;
36 import org.eclipse.swt.graphics.Image;
37 import org.eclipse.swt.graphics.Point;
38 import org.eclipse.swt.layout.GridData;
39 import org.eclipse.swt.widgets.Button;
40 import org.eclipse.swt.widgets.Composite;
41 import org.eclipse.swt.widgets.Control;
42 import org.eclipse.swt.widgets.Event;
43 import org.eclipse.swt.widgets.Listener;
44 import org.eclipse.swt.widgets.Shell;
45 import org.eclipse.swt.widgets.TableItem;
46 import org.eclipse.swt.widgets.Text;
47 import org.simantics.Simantics;
48 import org.simantics.databoard.Bindings;
49 import org.simantics.db.ReadGraph;
50 import org.simantics.db.Resource;
51 import org.simantics.db.common.NamedResource;
52 import org.simantics.db.common.request.ReadRequest;
53 import org.simantics.db.exception.DatabaseException;
54 import org.simantics.modeling.ModelingResources;
55 import org.simantics.modeling.typicals.AvailableSynchronizationRules;
56 import org.simantics.modeling.ui.Activator;
57 import org.simantics.utils.datastructures.Arrays;
58 import org.simantics.utils.strings.AlphanumComparator;
59
60
61 /**
62  * @author Antti Villberg
63  */
64 public class RuleChooserDialog extends Dialog {
65
66     public static class RuleResult {
67         public final Set<Resource> selectedRules;
68         public final boolean logging;
69
70         RuleResult(Set<Resource> selectedRules, boolean logging) {
71             this.selectedRules = selectedRules;
72             this.logging = logging;
73         }
74     }
75
76     private static final String DIALOG = "RuleChooserDialog"; //$NON-NLS-1$
77     private static final String LAST_SELECTION = "LastSelection"; //$NON-NLS-1$
78
79     private final NamedResource[]     rules;
80
81     private final String        title;
82
83     private final String        description;
84
85     private Collection<NamedResource> selectedRules;
86     private boolean             loggingEnabled = false;
87
88     private TableViewer         viewer;
89
90     private Button              logEnabled;
91
92     private IDialogSettings     dialogBoundsSettings;
93
94     private ResourceManager     resourceManager;
95
96     private final Comparator<NamedResource> sorter = new Comparator<NamedResource>() {
97         @Override
98         public int compare(NamedResource nr1, NamedResource nr2) {
99             return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(nr1.getName(), nr2.getName());
100         }
101     };
102
103     public RuleChooserDialog(Shell parent, String description, Collection<NamedResource> rules) {
104         super(parent);
105         this.rules = rules.toArray(new NamedResource[rules.size()]);
106         java.util.Arrays.sort(this.rules, sorter);
107         this.title = "Choose Synchronization Rules";
108         this.description = description;
109
110         IDialogSettings settings = Activator.getDefault().getDialogSettings();
111         dialogBoundsSettings = settings.getSection(DIALOG);
112         if (dialogBoundsSettings == null)
113             dialogBoundsSettings = settings.addNewSection(DIALOG);
114     }
115
116     @Override
117     protected IDialogSettings getDialogBoundsSettings() {
118         return dialogBoundsSettings;
119     }
120
121     @Override
122     protected void configureShell(Shell newShell) {
123         if (title != null) {
124             newShell.setText(title);
125         } else {
126             newShell.setText("Choose Action");
127         }
128         super.configureShell(newShell);
129     }
130
131     @Override
132     protected int getShellStyle() {
133         return super.getShellStyle() | SWT.RESIZE;
134     }
135
136     @Override
137     protected Point getInitialSize() {
138         Point defaultSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
139         Point result = super.getInitialSize();
140         if (defaultSize.equals(result))
141             return new Point(500, 500);
142         return result;
143     }
144
145     @Override
146     protected Control createDialogArea(Composite parent) {
147         Composite composite = (Composite) super.createDialogArea(parent);
148
149         this.resourceManager = new LocalResourceManager(JFaceResources.getResources());
150         composite.addListener(SWT.Dispose, new Listener() {
151             @Override
152             public void handleEvent(Event event) {
153                 resourceManager.dispose();
154                 resourceManager = null;
155             }
156         });
157
158         if (description != null) {
159             Text label = new Text(composite, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP);
160             label.setBackground(composite.getBackground());
161             label.setText(description);
162             label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
163         }
164
165         viewer = new TableViewer(composite, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER | SWT.SINGLE | SWT.CHECK);
166         viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
167         viewer.setContentProvider(new ArrayContentProvider());
168         viewer.setLabelProvider(new RuleLabelProvider());
169         viewer.setInput(rules);
170
171         viewer.addSelectionChangedListener(new ISelectionChangedListener() {
172             @Override
173             public void selectionChanged(SelectionChangedEvent event) {
174                 RuleChooserDialog.this.selectionChanged(event.getSelection());
175             }
176         });
177
178         logEnabled = new Button(composite, SWT.CHECK);
179         logEnabled.setText("Verbose synchronization logging");
180
181         if (rules.length > 0) {
182             viewer.setSelection(new StructuredSelection(rules[0]), true);
183             viewer.getTable().setFocus();
184         }
185
186         String[] lastChecked = dialogBoundsSettings.getArray(LAST_SELECTION);
187         if(lastChecked != null) {
188                 for(TableItem item : viewer.getTable().getItems()) {
189                         NamedResource nr = (NamedResource)item.getData(); 
190                         if(Arrays.contains(lastChecked, nr.getName()))
191                                 item.setChecked(true);
192                 }
193         }
194         
195         applyDialogFont(composite);
196         return composite;
197     }
198
199     private void selectionChanged(ISelection s) {
200         Button ok = getButton(IDialogConstants.OK_ID);
201         IStructuredSelection iss = (IStructuredSelection) s;
202         if (iss == null || iss.isEmpty()) {
203             if (ok != null)
204                 ok.setEnabled(false);
205             return;
206         }
207
208         if (ok != null)
209             ok.setEnabled(true);
210         return;
211     }
212
213     @Override
214     protected void okPressed() {
215
216         ArrayList<String> names = new ArrayList<String>(); 
217
218         selectedRules = new ArrayList<NamedResource>();
219         for(TableItem item : viewer.getTable().getItems()) {
220                 if(item.getChecked()) {
221                         NamedResource nr = (NamedResource)item.getData(); 
222                         selectedRules.add(nr);
223                         names.add(nr.getName());
224                 }
225         }
226         loggingEnabled = logEnabled.getSelection();
227         
228         dialogBoundsSettings.put(LAST_SELECTION, names.toArray(new String[names.size()]));
229         
230         super.okPressed();
231         
232     }
233
234     public Collection<NamedResource> getSelectedRules() {
235         return selectedRules;
236     }
237
238     public boolean isLoggingEnabled() {
239         return loggingEnabled;
240     }
241
242     class RuleLabelProvider extends LabelProvider {
243         @Override
244         public Image getImage(Object element) {
245                 return null;
246         }
247
248         @Override
249         public String getText(Object element) {
250             NamedResource nr = (NamedResource) element;
251             return nr.getName();
252         }
253     }
254     
255     public static RuleResult choose(Shell shell, String description, final Resource[] input) throws DatabaseException {
256
257         final Collection<NamedResource> rules = new HashSet<NamedResource>();
258         final Collection<Resource> alwaysEnabledRules = new HashSet<Resource>();
259         Simantics.getSession().syncRequest(new ReadRequest() {
260             @Override
261             public void run(ReadGraph graph) throws DatabaseException {
262                 ModelingResources MOD = ModelingResources.getInstance(graph);
263                 for(Resource r : input) {
264                     Collection<NamedResource> nrs = graph.syncRequest(new AvailableSynchronizationRules(r));
265                     for (NamedResource nr : nrs) {
266                         boolean alwaysEnabled = Boolean.TRUE.equals( graph.getPossibleRelatedValue(nr.getResource(), MOD.TypicalSynchronizationRule_alwaysEnabled, Bindings.BOOLEAN) );
267                         if (alwaysEnabled)
268                             alwaysEnabledRules.add(nr.getResource());
269                         else
270                             rules.add(nr);
271                     }
272                 }
273             }
274         });
275
276         description += "\n\nChecked rules will be applied in addition to default rules.";
277
278         RuleChooserDialog dialog = new RuleChooserDialog(shell, description, rules);
279         int ret = dialog.open();
280         if (ret != Window.OK)
281             return null;
282
283         Collection<NamedResource> selectedRules = dialog.getSelectedRules();
284
285         Set<Resource> selectedRuleResources = new HashSet<Resource>();
286         for(NamedResource nr : selectedRules) selectedRuleResources.add(nr.getResource());
287         selectedRuleResources.addAll(alwaysEnabledRules);
288
289         return new RuleResult(selectedRuleResources, dialog.isLoggingEnabled());
290
291     }
292
293 }