]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/preferences/DiagramPreferencePage.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / preferences / DiagramPreferencePage.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.modeling.ui.preferences;\r
13 \r
14 import java.text.DecimalFormat;\r
15 import java.text.ParseException;\r
16 \r
17 import org.eclipse.core.runtime.preferences.InstanceScope;\r
18 import org.eclipse.jface.layout.GridDataFactory;\r
19 import org.eclipse.jface.layout.GridLayoutFactory;\r
20 import org.eclipse.jface.preference.BooleanFieldEditor;\r
21 import org.eclipse.jface.preference.FieldEditor;\r
22 import org.eclipse.jface.preference.FieldEditorPreferencePage;\r
23 import org.eclipse.jface.preference.IPreferenceStore;\r
24 import org.eclipse.swt.SWT;\r
25 import org.eclipse.swt.events.DisposeEvent;\r
26 import org.eclipse.swt.events.DisposeListener;\r
27 import org.eclipse.swt.events.PaintEvent;\r
28 import org.eclipse.swt.events.PaintListener;\r
29 import org.eclipse.swt.graphics.GC;\r
30 import org.eclipse.swt.graphics.Point;\r
31 import org.eclipse.swt.layout.GridData;\r
32 import org.eclipse.swt.widgets.Button;\r
33 import org.eclipse.swt.widgets.Canvas;\r
34 import org.eclipse.swt.widgets.Combo;\r
35 import org.eclipse.swt.widgets.Composite;\r
36 import org.eclipse.swt.widgets.Event;\r
37 import org.eclipse.swt.widgets.Group;\r
38 import org.eclipse.swt.widgets.Label;\r
39 import org.eclipse.swt.widgets.Listener;\r
40 import org.eclipse.swt.widgets.Text;\r
41 import org.eclipse.ui.IWorkbench;\r
42 import org.eclipse.ui.IWorkbenchPreferencePage;\r
43 import org.eclipse.ui.preferences.ScopedPreferenceStore;\r
44 import org.osgi.service.prefs.BackingStoreException;\r
45 import org.simantics.modeling.ui.Activator;\r
46 import org.simantics.ui.workbench.preferences.NumberFieldEditor;\r
47 import org.simantics.utils.page.MarginUtils.Margin;\r
48 import org.simantics.utils.page.MarginUtils.Margins;\r
49 import org.simantics.utils.page.PageDesc;\r
50 import org.simantics.utils.page.PageOrientation;\r
51 import org.simantics.utils.ui.ErrorLogger;\r
52 \r
53 public class DiagramPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {\r
54 \r
55     public DiagramPreferencePage() {\r
56         super(GRID);\r
57     }\r
58 \r
59     @Override\r
60     public void init(IWorkbench workbench) {\r
61     }\r
62 \r
63     @Override\r
64     protected IPreferenceStore doGetPreferenceStore() {\r
65         return new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.PLUGIN_ID);\r
66     }\r
67 \r
68     @Override\r
69     protected void createFieldEditors() {\r
70         Group group = new Group(getFieldEditorParent(), SWT.NONE);\r
71         group.setText("Grid Snapping");\r
72         GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(group);\r
73 \r
74         NumberFieldEditor gridSizeField = new NumberFieldEditor(DiagramPreferences.P_SNAP_GRID_SIZE, "Grid size (mm)", group);\r
75         // 1um - 1m grid size allowed\r
76         gridSizeField.setValidRange(1e-3, 1e3);\r
77         addField(gridSizeField);\r
78 \r
79         GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(group);\r
80 \r
81         PageDescFieldEditor pageDescField = new PageDescFieldEditor(getFieldEditorParent());\r
82         addField(pageDescField);\r
83 \r
84         Group displayGroup = new Group(getFieldEditorParent(), SWT.NONE);\r
85         displayGroup.setText("Display");\r
86         GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(displayGroup);\r
87 \r
88         BooleanFieldEditor displayPage = new BooleanFieldEditor(DiagramPreferences.P_DISPLAY_PAGE_SIZE, "Show page borders", BooleanFieldEditor.SEPARATE_LABEL, displayGroup);\r
89         addField(displayPage);\r
90         BooleanFieldEditor displayMargins = new BooleanFieldEditor(DiagramPreferences.P_DISPLAY_MARGINS, "Show margins", BooleanFieldEditor.SEPARATE_LABEL, displayGroup);\r
91         addField(displayMargins);\r
92 \r
93         GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(displayGroup);\r
94     }\r
95 \r
96     static class PageDescFieldEditor extends FieldEditor {\r
97 \r
98         PageDesc desc;\r
99         PageDesc previousDesc;\r
100 \r
101         Group group;\r
102 \r
103         Button portrait;\r
104         Button landscape;\r
105         Combo combo;\r
106 \r
107         Text topMargin;\r
108         Text leftMargin;\r
109         Text rightMargin;\r
110         Text bottomMargin;\r
111 \r
112         Canvas pageCanvas;\r
113 \r
114         Listener marginListener = new Listener() {\r
115             @Override\r
116             public void handleEvent(Event event) {\r
117                 if (event.type == SWT.Modify) {\r
118                     Text txt = (Text) event.widget;\r
119                     String s = txt.getText();\r
120                     double value = 0;\r
121                     boolean invalid = false;\r
122                     try {\r
123                         value = DecimalFormat.getInstance().parse(s).doubleValue();\r
124                     } catch (ParseException e) {\r
125                         invalid = true;\r
126                     }\r
127                     if (invalid) {\r
128                         txt.setBackground(txt.getDisplay().getSystemColor(SWT.COLOR_RED));\r
129                     } else {\r
130                         txt.setBackground(null);\r
131                         int mask = txt == topMargin ? Margins.TOP : txt == leftMargin ? Margins.LEFT\r
132                                 : txt == rightMargin ? Margins.RIGHT : txt == bottomMargin ? Margins.BOTTOM : 0;\r
133                         Margin m = new Margin(0, 0, value);\r
134                         desc = desc.withMargins(desc.getMargins().withSide(mask, m));\r
135                         applyValuesToWidgets(false);\r
136                     }\r
137                 } else if (event.type == SWT.FocusIn) {\r
138                     Text txt = (Text) event.widget;\r
139                     txt.selectAll();\r
140                 }\r
141             }\r
142         };\r
143 \r
144         int[] marginEvents = { SWT.Modify, SWT.FocusIn };\r
145 \r
146         private void addMarginListeners() {\r
147             for (int et : marginEvents) {\r
148                 topMargin.addListener(et, marginListener);\r
149                 leftMargin.addListener(et, marginListener);\r
150                 rightMargin.addListener(et, marginListener);\r
151                 bottomMargin.addListener(et, marginListener);\r
152             }\r
153         }\r
154 \r
155         private void removeMarginListeners() {\r
156             for (int et : marginEvents) {\r
157                 topMargin.removeListener(et, marginListener);\r
158                 leftMargin.removeListener(et, marginListener);\r
159                 rightMargin.removeListener(et, marginListener);\r
160                 bottomMargin.removeListener(et, marginListener);\r
161             }\r
162         }\r
163 \r
164         public PageDescFieldEditor(Composite parent) {\r
165             DiagramPreferences prefs = DiagramPreferenceUtil.getPreferences();\r
166             desc = prefs.get(DiagramPreferences.P_DEFAULT_PAGE_SIZE);\r
167             previousDesc = desc;\r
168 \r
169             createControl(parent);\r
170         }\r
171 \r
172         @Override\r
173         protected void adjustForNumColumns(int numColumns) {\r
174             if (group != null) {\r
175                 ((GridData) group.getLayoutData()).horizontalSpan = numColumns;\r
176             }\r
177         }\r
178 \r
179         @Override\r
180         protected void doFillIntoGrid(Composite parent, int numColumns) {\r
181             group = getGroupControl(parent);\r
182             GridDataFactory.fillDefaults().grab(true, false).span(numColumns, 1).applyTo(group);\r
183         }\r
184 \r
185         /**\r
186          * Returns the change button for this field editor.\r
187          * @param parent The Composite to create the receiver in.\r
188          *\r
189          * @return the change button\r
190          */\r
191         protected Group getGroupControl(Composite parent) {\r
192             if (group == null) {\r
193                 group = new Group(parent, SWT.NONE);\r
194                 group.setText("Page Defaults");\r
195                 group.setToolTipText("The default settings for diagram pages.");\r
196                 group.setFont(parent.getFont());\r
197                 group.addDisposeListener(new DisposeListener() {\r
198                     public void widgetDisposed(DisposeEvent event) {\r
199                         group = null;\r
200                     }\r
201                 });\r
202                 GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(group);\r
203                 createChoosers(group);\r
204             } else {\r
205                 checkParent(group, parent);\r
206             }\r
207             return group;\r
208         }\r
209 \r
210         protected void createChoosers(Composite parent) {\r
211             //parent.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_BLUE));\r
212             Label label = new Label(parent, 0);\r
213             label.setText("Size:");\r
214             combo = new Combo(parent, 0);\r
215             combo.addListener(SWT.Selection, new Listener() {\r
216                 @Override\r
217                 public void handleEvent(Event event) {\r
218                     PageDesc pd = (PageDesc) combo.getData(combo.getItem(combo.getSelectionIndex()));\r
219                     if (pd != null) {\r
220                         desc = desc.withSizeFrom(pd).withText(pd.getText());\r
221                         applyValuesToWidgets();\r
222                     }\r
223                 }\r
224             });\r
225 \r
226             Composite marginComposite = new Composite(parent, 0);\r
227             //marginComposite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_RED));\r
228             GridDataFactory.fillDefaults().grab(true, true).grab(true, true).align(SWT.CENTER, SWT.CENTER).span(1, 2).applyTo(marginComposite);\r
229             GridLayoutFactory.fillDefaults().numColumns(3).margins(5, 5).spacing(3, 3).applyTo(marginComposite);\r
230             label = new Label(marginComposite, 0);\r
231             label.setText("Margins (mm)");\r
232 \r
233             GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.TOP).span(3, 1).applyTo(label);\r
234             label = new Label(marginComposite, 0);\r
235             GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.TOP).span(3, 1).applyTo(label);\r
236             new Label(marginComposite, 0);\r
237             topMargin = new Text(marginComposite, SWT.BORDER | SWT.CENTER);\r
238             GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(topMargin);\r
239             new Label(marginComposite, 0);\r
240             leftMargin = new Text(marginComposite, SWT.BORDER | SWT.RIGHT);\r
241             GridDataFactory.swtDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(leftMargin);\r
242             pageCanvas = new Canvas(marginComposite, 0);\r
243             GridDataFactory.swtDefaults().hint(SWT.DEFAULT, SWT.DEFAULT).grab(true, true).applyTo(pageCanvas);\r
244             pageCanvas.addPaintListener(new PaintListener() {\r
245                 @Override\r
246                 public void paintControl(PaintEvent e) {\r
247                     GC gc = e.gc;\r
248                     Point size = pageCanvas.getSize();\r
249 \r
250                     double w = desc.getOrientedWidth();\r
251                     double h = desc.getOrientedHeight();\r
252 \r
253                     Margins margins = desc.getMargins();\r
254                     int top = (int) Math.round(size.y * margins.top.diagramAbsolute / h);\r
255                     int bottom = (int) Math.round(size.y * margins.bottom.diagramAbsolute / h);\r
256                     int left = (int) Math.round(size.x * margins.left.diagramAbsolute / w);\r
257                     int right = (int) Math.round(size.x * margins.right.diagramAbsolute / w);\r
258 \r
259                     gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_GRAY));\r
260                     gc.fillRectangle(0, 0, size.x, size.y);\r
261 \r
262                     if ((top+bottom) < size.y && (left+right) < size.x) {\r
263                         gc.drawLine(left, 0, left, size.y-1);\r
264                         gc.drawLine(size.x-1-right, 0, size.x-1-right, size.y-1);\r
265                         gc.drawLine(0, top, size.x-1, top);\r
266                         gc.drawLine(0, size.y-1-bottom, size.x-1, size.y-1-bottom);\r
267 \r
268                         gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));\r
269                         gc.fillRectangle(left+1, top+1, size.x-2-right-left, size.y-2-top-bottom);\r
270                     }\r
271                 }\r
272             });\r
273             rightMargin = new Text(marginComposite, SWT.BORDER | SWT.LEFT);\r
274             GridDataFactory.swtDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(rightMargin);\r
275             new Label(marginComposite, 0);\r
276             bottomMargin = new Text(marginComposite, SWT.BORDER | SWT.CENTER);\r
277             GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(bottomMargin);\r
278             new Label(marginComposite, 0);\r
279 \r
280             addMarginListeners();\r
281 \r
282             label = new Label(parent, 0);\r
283             label.setText("Orientation:");\r
284             Composite comp = new Composite(parent, 0);\r
285             GridDataFactory.fillDefaults().span(1, 1).align(SWT.LEFT, SWT.CENTER).applyTo(comp);\r
286             GridLayoutFactory.fillDefaults().numColumns(1).applyTo(comp);\r
287             portrait = new Button(comp, SWT.RADIO);\r
288             landscape = new Button(comp, SWT.RADIO);\r
289             portrait.setText("Portrait");\r
290             landscape.setText("Landscape");\r
291 \r
292             Listener orientationListener = new Listener() {\r
293                 @Override\r
294                 public void handleEvent(Event event) {\r
295                     if (portrait.getSelection())\r
296                         desc = desc.withOrientation(PageOrientation.Portrait);\r
297                     else\r
298                         desc = desc.withOrientation(PageOrientation.Landscape);\r
299 \r
300                     applyValuesToWidgets();\r
301                 }\r
302             };\r
303             portrait.addListener(SWT.Selection, orientationListener);\r
304             landscape.addListener(SWT.Selection, orientationListener);\r
305 \r
306             PageDesc[] pds = PageDesc.getPredefinedDescriptions();\r
307             for (int i = 0; i < pds.length; ++i) {\r
308                 PageDesc pd = pds[i];\r
309                 combo.add(pd.getText());\r
310                 combo.setData(pd.getText(), pd);\r
311             }\r
312 \r
313             applyValuesToWidgets();\r
314         }\r
315 \r
316         @Override\r
317         protected void doLoad() {\r
318             if (group != null) {\r
319                 DiagramPreferences prefs = DiagramPreferenceUtil.getPreferences();\r
320 \r
321                 desc = prefs.get(DiagramPreferences.P_DEFAULT_PAGE_SIZE);\r
322                 previousDesc = desc;\r
323 \r
324                 applyValuesToWidgets();\r
325             }\r
326         }\r
327 \r
328         private void applyValuesToWidgets() {\r
329             applyValuesToWidgets(true);\r
330         }\r
331 \r
332         private void applyValuesToWidgets(boolean applyMargins) {\r
333                 PageOrientation orit = desc.getOrientation();\r
334             portrait.setSelection( orit == PageOrientation.Portrait );\r
335             landscape.setSelection(  orit == PageOrientation.Landscape );\r
336             String name = desc.getText();\r
337             int selectedIndex = combo.getSelectionIndex();\r
338             for (int i = 0; i < combo.getItemCount(); ++i) {\r
339                 String item = combo.getItem(i);\r
340                 if (name.equals(item)) {\r
341                     if (selectedIndex != i) {\r
342                         combo.select(i);\r
343                     }\r
344                     break;\r
345                 }\r
346             }\r
347 \r
348             if (applyMargins) {\r
349                 boolean marginEnabled = !desc.isInfinite();\r
350                 topMargin.setEnabled(marginEnabled);\r
351                 leftMargin.setEnabled(marginEnabled);\r
352                 rightMargin.setEnabled(marginEnabled);\r
353                 bottomMargin.setEnabled(marginEnabled);\r
354 \r
355                 if (marginEnabled) {\r
356                     removeMarginListeners();\r
357                     Margins margins = desc.getMargins();\r
358                     topMargin.setText(DecimalFormat.getNumberInstance().format(margins.top.diagramAbsolute));\r
359                     leftMargin.setText(DecimalFormat.getNumberInstance().format(margins.left.diagramAbsolute));\r
360                     rightMargin.setText(DecimalFormat.getNumberInstance().format(margins.right.diagramAbsolute));\r
361                     bottomMargin.setText(DecimalFormat.getNumberInstance().format(margins.bottom.diagramAbsolute));\r
362                     addMarginListeners();\r
363                 }\r
364             }\r
365 \r
366             layout(desc);\r
367         }\r
368 \r
369         void layout(PageDesc desc) {\r
370             double max = Math.max(desc.getOrientedWidth(), desc.getOrientedHeight());\r
371             double min = Math.min(desc.getOrientedWidth(), desc.getOrientedHeight());\r
372             double ratio = min / max;\r
373             int larger = 100;\r
374             int smaller = (int) Math.round(ratio*larger);\r
375 \r
376             boolean vertical = desc.getOrientedWidth() < desc.getOrientedHeight();\r
377 \r
378             GridData gd = (GridData) pageCanvas.getLayoutData();\r
379             gd.widthHint = vertical ? smaller : larger;\r
380             gd.heightHint = vertical ? larger : smaller;\r
381 \r
382             group.getParent().layout(true, true);\r
383             pageCanvas.redraw();\r
384         }\r
385 \r
386         @Override\r
387         protected void doLoadDefault() {\r
388             if (group != null) {\r
389                 DiagramPreferences prefs = DiagramPreferenceUtil.getDefaultPreferences();\r
390                 desc = prefs.get(DiagramPreferences.P_DEFAULT_PAGE_SIZE);\r
391                 previousDesc = desc;\r
392 \r
393                 applyValuesToWidgets();\r
394             }\r
395             // This is a workaround for a problem of not having a single preference backing this CommonsFieldEditor\r
396             setPresentsDefaultValue(false);\r
397         }\r
398 \r
399         @Override\r
400         protected void doStore() {\r
401             try {\r
402                 DiagramPreferenceUtil.flushPreferences(DiagramPreferenceUtil.getPreferences().withValue(DiagramPreferences.P_DEFAULT_PAGE_SIZE, desc));\r
403             } catch (BackingStoreException e) {\r
404                 ErrorLogger.defaultLogError("Could not store diagram preferences", e);\r
405             }\r
406         }\r
407 \r
408         @Override\r
409         public int getNumberOfControls() {\r
410             return 1;\r
411         }\r
412     }\r
413 \r
414 }\r