Mercurial > projects > dwt-addons
comparison dwtx/jface/preference/PreferenceDialog.d @ 9:6c14e54dfc11
completed /jface/resource/
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 29 Mar 2008 02:25:12 +0100 |
parents | |
children | b3c8e32d406f |
comparison
equal
deleted
inserted
replaced
8:a3ff22a98bef | 9:6c14e54dfc11 |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2007 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Teddy Walker <teddy.walker@googlemail.com> | |
11 * - Bug 188056 [Preferences] PreferencePages have to less indent in PreferenceDialog | |
12 * Port to the D programming language: | |
13 * Frank Benoit <benoit@tionex.de> | |
14 *******************************************************************************/ | |
15 module dwtx.jface.preference.PreferenceDialog; | |
16 | |
17 import dwt.dwthelper.utils; | |
18 | |
19 pragma( msg, "FIXME dwtx.jface.preference.PreferenceDialog" ); | |
20 class PreferenceDialog{ | |
21 public static const String PREF_DLG_TITLE_IMG = "preference_dialog_title_image"; //$NON-NLS-1$ | |
22 } | |
23 | |
24 /++ | |
25 import java.io.IOException; | |
26 import java.util.Iterator; | |
27 import java.util.List; | |
28 | |
29 import dwt.DWT; | |
30 import dwt.custom.BusyIndicator; | |
31 import dwt.custom.ScrolledComposite; | |
32 import dwt.events.ControlAdapter; | |
33 import dwt.events.ControlEvent; | |
34 import dwt.events.DisposeEvent; | |
35 import dwt.events.DisposeListener; | |
36 import dwt.events.HelpEvent; | |
37 import dwt.events.HelpListener; | |
38 import dwt.events.SelectionAdapter; | |
39 import dwt.events.SelectionEvent; | |
40 import dwt.events.ShellAdapter; | |
41 import dwt.events.ShellEvent; | |
42 import dwt.graphics.Font; | |
43 import dwt.graphics.Point; | |
44 import dwt.graphics.Rectangle; | |
45 import dwt.layout.FormAttachment; | |
46 import dwt.layout.FormData; | |
47 import dwt.layout.FormLayout; | |
48 import dwt.layout.GridData; | |
49 import dwt.layout.GridLayout; | |
50 import dwt.widgets.Button; | |
51 import dwt.widgets.Composite; | |
52 import dwt.widgets.Control; | |
53 import dwt.widgets.Event; | |
54 import dwt.widgets.Label; | |
55 import dwt.widgets.Layout; | |
56 import dwt.widgets.Listener; | |
57 import dwt.widgets.Sash; | |
58 import dwt.widgets.Shell; | |
59 import dwt.widgets.Tree; | |
60 import dwtx.core.runtime.Assert; | |
61 import dwtx.core.runtime.ISafeRunnable; | |
62 import dwtx.core.runtime.IStatus; | |
63 import dwtx.core.runtime.ListenerList; | |
64 import dwtx.core.runtime.SafeRunner; | |
65 import dwtx.core.runtime.Status; | |
66 import dwtx.jface.dialogs.DialogMessageArea; | |
67 import dwtx.jface.dialogs.IDialogConstants; | |
68 import dwtx.jface.dialogs.IMessageProvider; | |
69 import dwtx.jface.dialogs.IPageChangeProvider; | |
70 import dwtx.jface.dialogs.IPageChangedListener; | |
71 import dwtx.jface.dialogs.MessageDialog; | |
72 import dwtx.jface.dialogs.PageChangedEvent; | |
73 import dwtx.jface.dialogs.TrayDialog; | |
74 import dwtx.jface.resource.JFaceResources; | |
75 import dwtx.jface.util.IPropertyChangeListener; | |
76 import dwtx.jface.util.Policy; | |
77 import dwtx.jface.util.PropertyChangeEvent; | |
78 import dwtx.jface.util.SafeRunnable; | |
79 import dwtx.jface.viewers.ISelection; | |
80 import dwtx.jface.viewers.ISelectionChangedListener; | |
81 import dwtx.jface.viewers.IStructuredSelection; | |
82 import dwtx.jface.viewers.SelectionChangedEvent; | |
83 import dwtx.jface.viewers.StructuredSelection; | |
84 import dwtx.jface.viewers.TreeViewer; | |
85 import dwtx.jface.viewers.ViewerFilter; | |
86 | |
87 /** | |
88 * A preference dialog is a hierarchical presentation of preference pages. Each | |
89 * page is represented by a node in the tree shown on the left hand side of the | |
90 * dialog; when a node is selected, the corresponding page is shown on the right | |
91 * hand side. | |
92 */ | |
93 public class PreferenceDialog extends TrayDialog implements IPreferencePageContainer, IPageChangeProvider { | |
94 /** | |
95 * Layout for the page container. | |
96 * | |
97 */ | |
98 private class PageLayout extends Layout { | |
99 public Point computeSize(Composite composite, int wHint, int hHint, bool force) { | |
100 if (wHint !is DWT.DEFAULT && hHint !is DWT.DEFAULT) { | |
101 return new Point(wHint, hHint); | |
102 } | |
103 int x = minimumPageSize.x; | |
104 int y = minimumPageSize.y; | |
105 Control[] children = composite.getChildren(); | |
106 for (int i = 0; i < children.length; i++) { | |
107 Point size = children[i].computeSize(DWT.DEFAULT, DWT.DEFAULT, force); | |
108 x = Math.max(x, size.x); | |
109 y = Math.max(y, size.y); | |
110 } | |
111 | |
112 //As pages can implement thier own computeSize | |
113 //take it into account | |
114 if(currentPage !is null){ | |
115 Point size = currentPage.computeSize(); | |
116 x = Math.max(x, size.x); | |
117 y = Math.max(y, size.y); | |
118 } | |
119 | |
120 if (wHint !is DWT.DEFAULT) { | |
121 x = wHint; | |
122 } | |
123 if (hHint !is DWT.DEFAULT) { | |
124 y = hHint; | |
125 } | |
126 return new Point(x, y); | |
127 } | |
128 | |
129 public void layout(Composite composite, bool force) { | |
130 Rectangle rect = composite.getClientArea(); | |
131 Control[] children = composite.getChildren(); | |
132 for (int i = 0; i < children.length; i++) { | |
133 children[i].setSize(rect.width, rect.height); | |
134 } | |
135 } | |
136 } | |
137 | |
138 //The id of the last page that was selected | |
139 private static String lastPreferenceId = null; | |
140 | |
141 //The last known tree width | |
142 private static int lastTreeWidth = 180; | |
143 | |
144 /** | |
145 * Indentifier for the error image | |
146 */ | |
147 public static final String PREF_DLG_IMG_TITLE_ERROR = DLG_IMG_MESSAGE_ERROR; | |
148 | |
149 /** | |
150 * Title area fields | |
151 */ | |
152 public static final String PREF_DLG_TITLE_IMG = "preference_dialog_title_image"; //$NON-NLS-1$ | |
153 | |
154 /** | |
155 * Return code used when dialog failed | |
156 */ | |
157 protected static final int FAILED = 2; | |
158 | |
159 /** | |
160 * The current preference page, or <code>null</code> if there is none. | |
161 */ | |
162 private IPreferencePage currentPage; | |
163 | |
164 private DialogMessageArea messageArea; | |
165 | |
166 private Point lastShellSize; | |
167 | |
168 private IPreferenceNode lastSuccessfulNode; | |
169 | |
170 /** | |
171 * The minimum page size; 400 by 400 by default. | |
172 * | |
173 * @see #setMinimumPageSize(Point) | |
174 */ | |
175 private Point minimumPageSize = new Point(400, 400); | |
176 | |
177 /** | |
178 * The OK button. | |
179 */ | |
180 private Button okButton; | |
181 | |
182 /** | |
183 * The Composite in which a page is shown. | |
184 */ | |
185 private Composite pageContainer; | |
186 | |
187 /** | |
188 * The preference manager. | |
189 */ | |
190 private PreferenceManager preferenceManager; | |
191 | |
192 /** | |
193 * Flag for the presence of the error message. | |
194 */ | |
195 private bool showingError = false; | |
196 | |
197 /** | |
198 * Preference store, initially <code>null</code> meaning none. | |
199 * | |
200 * @see #setPreferenceStore | |
201 */ | |
202 private IPreferenceStore preferenceStore; | |
203 | |
204 private Composite titleArea; | |
205 | |
206 /** | |
207 * The tree viewer. | |
208 */ | |
209 private TreeViewer treeViewer; | |
210 | |
211 private ListenerList pageChangedListeners = new ListenerList(); | |
212 | |
213 /** | |
214 * Composite with a FormLayout to contain the title area | |
215 */ | |
216 Composite formTitleComposite; | |
217 | |
218 private ScrolledComposite scrolled; | |
219 | |
220 /** | |
221 * Creates a new preference dialog under the control of the given preference | |
222 * manager. | |
223 * | |
224 * @param parentShell | |
225 * the parent shell | |
226 * @param manager | |
227 * the preference manager | |
228 */ | |
229 public PreferenceDialog(Shell parentShell, PreferenceManager manager) { | |
230 super(parentShell); | |
231 setShellStyle(getShellStyle() | DWT.RESIZE | DWT.MAX); | |
232 preferenceManager = manager; | |
233 } | |
234 | |
235 /* | |
236 * (non-Javadoc) | |
237 * | |
238 * @see dwtx.jface.dialogs.Dialog#buttonPressed(int) | |
239 */ | |
240 protected void buttonPressed(int buttonId) { | |
241 switch (buttonId) { | |
242 case IDialogConstants.OK_ID: { | |
243 okPressed(); | |
244 return; | |
245 } | |
246 case IDialogConstants.CANCEL_ID: { | |
247 cancelPressed(); | |
248 return; | |
249 } | |
250 case IDialogConstants.HELP_ID: { | |
251 helpPressed(); | |
252 return; | |
253 } | |
254 } | |
255 } | |
256 | |
257 /* | |
258 * (non-Javadoc) | |
259 * | |
260 * @see dwtx.jface.dialogs.Dialog#cancelPressed() | |
261 */ | |
262 protected void cancelPressed() { | |
263 // Inform all pages that we are cancelling | |
264 Iterator nodes = preferenceManager.getElements(PreferenceManager.PRE_ORDER).iterator(); | |
265 while (nodes.hasNext()) { | |
266 final IPreferenceNode node = (IPreferenceNode) nodes.next(); | |
267 if (getPage(node) !is null) { | |
268 SafeRunnable.run(new SafeRunnable() { | |
269 public void run() { | |
270 if (!getPage(node).performCancel()) { | |
271 return; | |
272 } | |
273 } | |
274 }); | |
275 } | |
276 } | |
277 setReturnCode(CANCEL); | |
278 close(); | |
279 } | |
280 | |
281 /** | |
282 * Clear the last selected node. This is so that we not chache the last | |
283 * selection in case of an error. | |
284 */ | |
285 void clearSelectedNode() { | |
286 setSelectedNodePreference(null); | |
287 } | |
288 | |
289 /* | |
290 * (non-Javadoc) | |
291 * | |
292 * @see dwtx.jface.window.Window#close() | |
293 */ | |
294 public bool close() { | |
295 | |
296 //Do this is in a SafeRunnable as it may run client code | |
297 SafeRunnable runnable = new SafeRunnable(){ | |
298 /* (non-Javadoc) | |
299 * @see dwtx.core.runtime.ISafeRunnable#run() | |
300 */ | |
301 public void run() throws Exception { | |
302 List nodes = preferenceManager.getElements(PreferenceManager.PRE_ORDER); | |
303 for (int i = 0; i < nodes.size(); i++) { | |
304 IPreferenceNode node = (IPreferenceNode) nodes.get(i); | |
305 node.disposeResources(); | |
306 } | |
307 | |
308 } | |
309 | |
310 /* (non-Javadoc) | |
311 * @see dwtx.jface.util.SafeRunnable#handleException(java.lang.Throwable) | |
312 */ | |
313 public void handleException(Throwable e) { | |
314 super.handleException(e); | |
315 clearSelectedNode();//Do not cache a node with problems | |
316 } | |
317 }; | |
318 | |
319 SafeRunner.run(runnable); | |
320 | |
321 return super.close(); | |
322 } | |
323 | |
324 /* | |
325 * (non-Javadoc) | |
326 * | |
327 * @see dwtx.jface.window.Window#configureShell(dwt.widgets.Shell) | |
328 */ | |
329 protected void configureShell(Shell newShell) { | |
330 super.configureShell(newShell); | |
331 newShell.setText(JFaceResources.getString("PreferenceDialog.title")); //$NON-NLS-1$ | |
332 newShell.addShellListener(new ShellAdapter() { | |
333 public void shellActivated(ShellEvent e) { | |
334 if (lastShellSize is null) { | |
335 lastShellSize = getShell().getSize(); | |
336 } | |
337 } | |
338 | |
339 }); | |
340 | |
341 } | |
342 | |
343 /* | |
344 * (non-Javadoc) | |
345 * | |
346 * @see dwtx.jface.window.Window#constrainShellSize() | |
347 */ | |
348 protected void constrainShellSize() { | |
349 super.constrainShellSize(); | |
350 // record opening shell size | |
351 if (lastShellSize is null) { | |
352 lastShellSize = getShell().getSize(); | |
353 } | |
354 } | |
355 | |
356 /* | |
357 * (non-Javadoc) | |
358 * | |
359 * @see dwtx.jface.dialogs.Dialog#createButtonsForButtonBar(dwt.widgets.Composite) | |
360 */ | |
361 protected void createButtonsForButtonBar(Composite parent) { | |
362 // create OK and Cancel buttons by default | |
363 okButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); | |
364 getShell().setDefaultButton(okButton); | |
365 createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); | |
366 } | |
367 | |
368 /* | |
369 * (non-Javadoc) | |
370 * | |
371 * @see dwtx.jface.window.Window#createContents(dwt.widgets.Composite) | |
372 */ | |
373 protected Control createContents(final Composite parent) { | |
374 final Control[] control = new Control[1]; | |
375 BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() { | |
376 public void run() { | |
377 control[0] = PreferenceDialog.super.createContents(parent); | |
378 // Add the first page | |
379 selectSavedItem(); | |
380 } | |
381 }); | |
382 | |
383 return control[0]; | |
384 } | |
385 | |
386 /* | |
387 * (non-Javadoc) | |
388 * | |
389 * @see dwtx.jface.dialogs.Dialog#createDialogArea(dwt.widgets.Composite) | |
390 */ | |
391 protected Control createDialogArea(Composite parent) { | |
392 final Composite composite = (Composite) super.createDialogArea(parent); | |
393 GridLayout parentLayout = ((GridLayout) composite.getLayout()); | |
394 parentLayout.numColumns = 4; | |
395 parentLayout.marginHeight = 0; | |
396 parentLayout.marginWidth = 0; | |
397 parentLayout.verticalSpacing = 0; | |
398 parentLayout.horizontalSpacing = 0; | |
399 | |
400 composite.setBackground(parent.getDisplay().getSystemColor(DWT.COLOR_LIST_BACKGROUND)); | |
401 | |
402 Control treeControl = createTreeAreaContents(composite); | |
403 createSash(composite,treeControl); | |
404 | |
405 Label versep = new Label(composite, DWT.SEPARATOR | DWT.VERTICAL); | |
406 GridData verGd = new GridData(GridData.FILL_VERTICAL | GridData.GRAB_VERTICAL); | |
407 | |
408 versep.setLayoutData(verGd); | |
409 versep.setLayoutData(new GridData(DWT.LEFT, DWT.FILL, false, true)); | |
410 | |
411 Composite pageAreaComposite = new Composite(composite, DWT.NONE); | |
412 pageAreaComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); | |
413 GridLayout layout = new GridLayout(1, true); | |
414 layout.marginHeight = 0; | |
415 layout.marginWidth = 0; | |
416 layout.verticalSpacing = 0; | |
417 pageAreaComposite.setLayout(layout); | |
418 | |
419 formTitleComposite = new Composite(pageAreaComposite, DWT.NONE); | |
420 FormLayout titleLayout = new FormLayout(); | |
421 titleLayout.marginWidth = 0; | |
422 titleLayout.marginHeight = 0; | |
423 formTitleComposite.setLayout(titleLayout); | |
424 | |
425 GridData titleGridData = new GridData(GridData.FILL_HORIZONTAL); | |
426 titleGridData.horizontalIndent = IDialogConstants.HORIZONTAL_MARGIN; | |
427 formTitleComposite.setLayoutData(titleGridData); | |
428 | |
429 // Build the title area and separator line | |
430 Composite titleComposite = new Composite(formTitleComposite, DWT.NONE); | |
431 layout = new GridLayout(); | |
432 layout.marginBottom = 5; | |
433 layout.marginHeight = 0; | |
434 layout.marginWidth = 0; | |
435 layout.horizontalSpacing = 0; | |
436 titleComposite.setLayout(layout); | |
437 | |
438 FormData titleFormData = new FormData(); | |
439 titleFormData.top = new FormAttachment(0,0); | |
440 titleFormData.left = new FormAttachment(0,0); | |
441 titleFormData.right = new FormAttachment(100,0); | |
442 titleFormData.bottom = new FormAttachment(100,0); | |
443 | |
444 titleComposite.setLayoutData(titleFormData); | |
445 createTitleArea(titleComposite); | |
446 | |
447 Label separator = new Label(pageAreaComposite, DWT.HORIZONTAL | DWT.SEPARATOR); | |
448 | |
449 separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL)); | |
450 | |
451 | |
452 // Build the Page container | |
453 pageContainer = createPageContainer(pageAreaComposite); | |
454 GridData pageContainerData = new GridData(GridData.FILL_BOTH); | |
455 pageContainerData.horizontalIndent = IDialogConstants.HORIZONTAL_MARGIN; | |
456 pageContainer.setLayoutData(pageContainerData); | |
457 // Build the separator line | |
458 Label bottomSeparator = new Label(parent, DWT.HORIZONTAL | DWT.SEPARATOR); | |
459 bottomSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL)); | |
460 return composite; | |
461 } | |
462 | |
463 /** | |
464 * Create the sash with right control on the right. Note | |
465 * that this method assumes GridData for the layout data | |
466 * of the rightControl. | |
467 * @param composite | |
468 * @param rightControl | |
469 * @return Sash | |
470 * | |
471 * @since 3.1 | |
472 */ | |
473 protected Sash createSash(final Composite composite, final Control rightControl) { | |
474 final Sash sash = new Sash(composite, DWT.VERTICAL); | |
475 sash.setLayoutData(new GridData(GridData.FILL_VERTICAL)); | |
476 sash.setBackground(composite.getDisplay().getSystemColor(DWT.COLOR_LIST_BACKGROUND)); | |
477 // the following listener resizes the tree control based on sash deltas. | |
478 // If necessary, it will also grow/shrink the dialog. | |
479 sash.addListener(DWT.Selection, new Listener() { | |
480 /* | |
481 * (non-Javadoc) | |
482 * | |
483 * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event) | |
484 */ | |
485 public void handleEvent(Event event) { | |
486 if (event.detail is DWT.DRAG) { | |
487 return; | |
488 } | |
489 int shift = event.x - sash.getBounds().x; | |
490 GridData data = (GridData) rightControl.getLayoutData(); | |
491 int newWidthHint = data.widthHint + shift; | |
492 if (newWidthHint < 20) { | |
493 return; | |
494 } | |
495 Point computedSize = getShell().computeSize(DWT.DEFAULT, DWT.DEFAULT); | |
496 Point currentSize = getShell().getSize(); | |
497 // if the dialog wasn't of a custom size we know we can shrink | |
498 // it if necessary based on sash movement. | |
499 bool customSize = !computedSize.equals(currentSize); | |
500 data.widthHint = newWidthHint; | |
501 setLastTreeWidth(newWidthHint); | |
502 composite.layout(true); | |
503 // recompute based on new widget size | |
504 computedSize = getShell().computeSize(DWT.DEFAULT, DWT.DEFAULT); | |
505 // if the dialog was of a custom size then increase it only if | |
506 // necessary. | |
507 if (customSize) { | |
508 computedSize.x = Math.max(computedSize.x, currentSize.x); | |
509 } | |
510 computedSize.y = Math.max(computedSize.y, currentSize.y); | |
511 if (computedSize.equals(currentSize)) { | |
512 return; | |
513 } | |
514 setShellSize(computedSize.x, computedSize.y); | |
515 lastShellSize = getShell().getSize(); | |
516 } | |
517 }); | |
518 return sash; | |
519 } | |
520 | |
521 /** | |
522 * Creates the inner page container. | |
523 * | |
524 * @param parent | |
525 * @return Composite | |
526 */ | |
527 protected Composite createPageContainer(Composite parent) { | |
528 | |
529 Composite outer = new Composite(parent, DWT.NONE); | |
530 | |
531 GridData outerData = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | |
532 | GridData.GRAB_VERTICAL); | |
533 outerData.horizontalIndent = IDialogConstants.HORIZONTAL_MARGIN; | |
534 | |
535 outer.setLayout(new GridLayout()); | |
536 outer.setLayoutData(outerData); | |
537 | |
538 //Create an outer composite for spacing | |
539 scrolled = new ScrolledComposite(outer, DWT.V_SCROLL | DWT.H_SCROLL); | |
540 | |
541 scrolled.setExpandHorizontal(true); | |
542 scrolled.setExpandVertical(true); | |
543 | |
544 GridData scrolledData = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | |
545 | GridData.GRAB_VERTICAL); | |
546 | |
547 scrolled.setLayoutData(scrolledData); | |
548 | |
549 Composite result = new Composite(scrolled, DWT.NONE); | |
550 | |
551 GridData resultData = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | |
552 | GridData.GRAB_VERTICAL); | |
553 | |
554 result.setLayout(getPageLayout()); | |
555 result.setLayoutData(resultData); | |
556 | |
557 scrolled.setContent(result); | |
558 | |
559 return result; | |
560 } | |
561 | |
562 /** | |
563 * Return the layout for the composite that contains | |
564 * the pages. | |
565 * @return PageLayout | |
566 * | |
567 * @since 3.1 | |
568 */ | |
569 protected Layout getPageLayout() { | |
570 return new PageLayout(); | |
571 } | |
572 | |
573 /** | |
574 * Creates the wizard's title area. | |
575 * | |
576 * @param parent | |
577 * the DWT parent for the title area composite. | |
578 * @return the created title area composite. | |
579 */ | |
580 protected Composite createTitleArea(Composite parent) { | |
581 // Create the title area which will contain | |
582 // a title, message, and image. | |
583 int margins = 2; | |
584 titleArea = new Composite(parent, DWT.NONE); | |
585 FormLayout layout = new FormLayout(); | |
586 layout.marginHeight = 0; | |
587 layout.marginWidth = margins; | |
588 titleArea.setLayout(layout); | |
589 | |
590 | |
591 GridData layoutData = new GridData(GridData.FILL_HORIZONTAL); | |
592 layoutData.verticalAlignment = DWT.TOP; | |
593 titleArea.setLayoutData(layoutData); | |
594 | |
595 // Message label | |
596 messageArea = new DialogMessageArea(); | |
597 messageArea.createContents(titleArea); | |
598 | |
599 titleArea.addControlListener(new ControlAdapter() { | |
600 /* (non-Javadoc) | |
601 * @see dwt.events.ControlAdapter#controlResized(dwt.events.ControlEvent) | |
602 */ | |
603 public void controlResized(ControlEvent e) { | |
604 updateMessage(); | |
605 } | |
606 }); | |
607 | |
608 final IPropertyChangeListener fontListener = new IPropertyChangeListener() { | |
609 public void propertyChange(PropertyChangeEvent event) { | |
610 if (JFaceResources.BANNER_FONT.equals(event.getProperty())) { | |
611 updateMessage(); | |
612 } | |
613 if (JFaceResources.DIALOG_FONT.equals(event.getProperty())) { | |
614 updateMessage(); | |
615 Font dialogFont = JFaceResources.getDialogFont(); | |
616 updateTreeFont(dialogFont); | |
617 Control[] children = ((Composite) buttonBar).getChildren(); | |
618 for (int i = 0; i < children.length; i++) { | |
619 children[i].setFont(dialogFont); | |
620 } | |
621 } | |
622 } | |
623 }; | |
624 | |
625 titleArea.addDisposeListener(new DisposeListener() { | |
626 public void widgetDisposed(DisposeEvent event) { | |
627 JFaceResources.getFontRegistry().removeListener(fontListener); | |
628 } | |
629 }); | |
630 JFaceResources.getFontRegistry().addListener(fontListener); | |
631 messageArea.setTitleLayoutData(createMessageAreaData()); | |
632 messageArea.setMessageLayoutData(createMessageAreaData()); | |
633 return titleArea; | |
634 } | |
635 | |
636 /** | |
637 * Create the layout data for the message area. | |
638 * | |
639 * @return FormData for the message area. | |
640 */ | |
641 private FormData createMessageAreaData() { | |
642 FormData messageData = new FormData(); | |
643 messageData.top = new FormAttachment(0); | |
644 messageData.bottom = new FormAttachment(100); | |
645 messageData.right = new FormAttachment(100); | |
646 messageData.left = new FormAttachment(0); | |
647 return messageData; | |
648 } | |
649 | |
650 /** | |
651 * @param parent | |
652 * the DWT parent for the tree area controls. | |
653 * @return the new <code>Control</code>. | |
654 * @since 3.0 | |
655 */ | |
656 protected Control createTreeAreaContents(Composite parent) { | |
657 // Build the tree an put it into the composite. | |
658 treeViewer = createTreeViewer(parent); | |
659 treeViewer.setInput(getPreferenceManager()); | |
660 updateTreeFont(JFaceResources.getDialogFont()); | |
661 layoutTreeAreaControl(treeViewer.getControl()); | |
662 return treeViewer.getControl(); | |
663 } | |
664 | |
665 /** | |
666 * Create a new <code>TreeViewer</code>. | |
667 * | |
668 * @param parent | |
669 * the parent <code>Composite</code>. | |
670 * @return the <code>TreeViewer</code>. | |
671 * @since 3.0 | |
672 */ | |
673 protected TreeViewer createTreeViewer(Composite parent) { | |
674 final TreeViewer viewer = new TreeViewer(parent, DWT.NONE); | |
675 addListeners(viewer); | |
676 viewer.setLabelProvider(new PreferenceLabelProvider()); | |
677 viewer.setContentProvider(new PreferenceContentProvider()); | |
678 return viewer; | |
679 } | |
680 | |
681 /** | |
682 * Add the listeners to the tree viewer. | |
683 * @param viewer | |
684 * | |
685 * @since 3.1 | |
686 */ | |
687 protected void addListeners(final TreeViewer viewer) { | |
688 viewer.addPostSelectionChangedListener(new ISelectionChangedListener() { | |
689 private void handleError() { | |
690 try { | |
691 // remove the listener temporarily so that the events caused | |
692 // by the error handling dont further cause error handling | |
693 // to occur. | |
694 viewer.removePostSelectionChangedListener(this); | |
695 showPageFlippingAbortDialog(); | |
696 selectCurrentPageAgain(); | |
697 clearSelectedNode(); | |
698 } finally { | |
699 viewer.addPostSelectionChangedListener(this); | |
700 } | |
701 } | |
702 | |
703 public void selectionChanged(SelectionChangedEvent event) { | |
704 Object selection = getSingleSelection(event.getSelection()); | |
705 if (selection instanceof IPreferenceNode) { | |
706 if (!isCurrentPageValid()) { | |
707 handleError(); | |
708 } else if (!showPage((IPreferenceNode) selection)) { | |
709 // Page flipping wasn't successful | |
710 handleError(); | |
711 } else { | |
712 // Everything went well | |
713 lastSuccessfulNode = (IPreferenceNode) selection; | |
714 } | |
715 } | |
716 } | |
717 }); | |
718 ((Tree) viewer.getControl()).addSelectionListener(new SelectionAdapter() { | |
719 public void widgetDefaultSelected(final SelectionEvent event) { | |
720 ISelection selection = viewer.getSelection(); | |
721 if (selection.isEmpty()) { | |
722 return; | |
723 } | |
724 IPreferenceNode singleSelection = getSingleSelection(selection); | |
725 bool expanded = viewer.getExpandedState(singleSelection); | |
726 viewer.setExpandedState(singleSelection, !expanded); | |
727 } | |
728 }); | |
729 //Register help listener on the tree to use context sensitive help | |
730 viewer.getControl().addHelpListener(new HelpListener() { | |
731 public void helpRequested(HelpEvent event) { | |
732 // call perform help on the current page | |
733 if (currentPage !is null) { | |
734 currentPage.performHelp(); | |
735 } | |
736 } | |
737 }); | |
738 } | |
739 | |
740 /** | |
741 * Find the <code>IPreferenceNode</code> that has data the same id as the | |
742 * supplied value. | |
743 * | |
744 * @param nodeId | |
745 * the id to search for. | |
746 * @return <code>IPreferenceNode</code> or <code>null</code> if not | |
747 * found. | |
748 */ | |
749 protected IPreferenceNode findNodeMatching(String nodeId) { | |
750 List nodes = preferenceManager.getElements(PreferenceManager.POST_ORDER); | |
751 for (Iterator i = nodes.iterator(); i.hasNext();) { | |
752 IPreferenceNode node = (IPreferenceNode) i.next(); | |
753 if (node.getId().equals(nodeId)) { | |
754 return node; | |
755 } | |
756 } | |
757 return null; | |
758 } | |
759 | |
760 /** | |
761 * Get the last known right side width. | |
762 * | |
763 * @return the width. | |
764 */ | |
765 protected int getLastRightWidth() { | |
766 return lastTreeWidth; | |
767 } | |
768 | |
769 /** | |
770 * Returns the preference mananger used by this preference dialog. | |
771 * | |
772 * @return the preference mananger | |
773 */ | |
774 public PreferenceManager getPreferenceManager() { | |
775 return preferenceManager; | |
776 } | |
777 | |
778 /* | |
779 * (non-Javadoc) | |
780 * | |
781 * @see dwtx.jface.preference.IPreferencePageContainer#getPreferenceStore() | |
782 */ | |
783 public IPreferenceStore getPreferenceStore() { | |
784 return preferenceStore; | |
785 } | |
786 | |
787 /** | |
788 * Get the name of the selected item preference | |
789 * | |
790 * @return String | |
791 */ | |
792 protected String getSelectedNodePreference() { | |
793 return lastPreferenceId; | |
794 } | |
795 | |
796 /** | |
797 * @param selection | |
798 * the <code>ISelection</code> to examine. | |
799 * @return the first element, or null if empty. | |
800 */ | |
801 protected IPreferenceNode getSingleSelection(ISelection selection) { | |
802 if (!selection.isEmpty()) { | |
803 IStructuredSelection structured = (IStructuredSelection) selection; | |
804 if (structured.getFirstElement() instanceof IPreferenceNode) { | |
805 return (IPreferenceNode) structured.getFirstElement(); | |
806 } | |
807 } | |
808 return null; | |
809 } | |
810 | |
811 /** | |
812 * @return the <code>TreeViewer</code> for this dialog. | |
813 * @since 3.3 | |
814 */ | |
815 public TreeViewer getTreeViewer() { | |
816 return treeViewer; | |
817 } | |
818 | |
819 /** | |
820 * Save the values specified in the pages. | |
821 * <p> | |
822 * The default implementation of this framework method saves all pages of | |
823 * type <code>PreferencePage</code> (if their store needs saving and is a | |
824 * <code>PreferenceStore</code>). | |
825 * </p> | |
826 * <p> | |
827 * Subclasses may override. | |
828 * </p> | |
829 */ | |
830 protected void handleSave() { | |
831 Iterator nodes = preferenceManager.getElements(PreferenceManager.PRE_ORDER).iterator(); | |
832 while (nodes.hasNext()) { | |
833 IPreferenceNode node = (IPreferenceNode) nodes.next(); | |
834 IPreferencePage page = node.getPage(); | |
835 if (page instanceof PreferencePage) { | |
836 // Save now in case tbe workbench does not shutdown cleanly | |
837 IPreferenceStore store = ((PreferencePage) page).getPreferenceStore(); | |
838 if (store !is null && store.needsSaving() | |
839 && store instanceof IPersistentPreferenceStore) { | |
840 try { | |
841 ((IPersistentPreferenceStore) store).save(); | |
842 } catch (IOException e) { | |
843 MessageDialog | |
844 .openError( | |
845 getShell(), | |
846 JFaceResources.getString("PreferenceDialog.saveErrorTitle"), //$NON-NLS-1$ | |
847 JFaceResources | |
848 .format( | |
849 "PreferenceDialog.saveErrorMessage", new Object[] { page.getTitle(), e.getMessage() })); //$NON-NLS-1$ | |
850 } | |
851 } | |
852 } | |
853 } | |
854 } | |
855 | |
856 /** | |
857 * Notifies that the window's close button was pressed, the close menu was | |
858 * selected, or the ESCAPE key pressed. | |
859 * <p> | |
860 * The default implementation of this framework method sets the window's | |
861 * return code to <code>CANCEL</code> and closes the window using | |
862 * <code>close</code>. Subclasses may extend or reimplement. | |
863 * </p> | |
864 */ | |
865 protected void handleShellCloseEvent() { | |
866 // handle the same as pressing cancel | |
867 cancelPressed(); | |
868 } | |
869 | |
870 /** | |
871 * Notifies of the pressing of the Help button. | |
872 * <p> | |
873 * The default implementation of this framework method calls | |
874 * <code>performHelp</code> on the currently active page. | |
875 * </p> | |
876 */ | |
877 protected void helpPressed() { | |
878 if (currentPage !is null) { | |
879 currentPage.performHelp(); | |
880 } | |
881 } | |
882 | |
883 /** | |
884 * Returns whether the current page is valid. | |
885 * | |
886 * @return <code>false</code> if the current page is not valid, or or | |
887 * <code>true</code> if the current page is valid or there is no | |
888 * current page | |
889 */ | |
890 protected bool isCurrentPageValid() { | |
891 if (currentPage is null) { | |
892 return true; | |
893 } | |
894 return currentPage.isValid(); | |
895 } | |
896 | |
897 /** | |
898 * @param control | |
899 * the <code>Control</code> to lay out. | |
900 * @since 3.0 | |
901 */ | |
902 protected void layoutTreeAreaControl(Control control) { | |
903 GridData gd = new GridData(GridData.FILL_VERTICAL); | |
904 gd.widthHint = getLastRightWidth(); | |
905 gd.verticalSpan = 1; | |
906 control.setLayoutData(gd); | |
907 } | |
908 | |
909 /** | |
910 * The preference dialog implementation of this <code>Dialog</code> | |
911 * framework method sends <code>performOk</code> to all pages of the | |
912 * preference dialog, then calls <code>handleSave</code> on this dialog to | |
913 * save any state, and then calls <code>close</code> to close this dialog. | |
914 */ | |
915 protected void okPressed() { | |
916 SafeRunnable.run(new SafeRunnable() { | |
917 private bool errorOccurred; | |
918 | |
919 /* | |
920 * (non-Javadoc) | |
921 * | |
922 * @see dwtx.core.runtime.ISafeRunnable#run() | |
923 */ | |
924 public void run() { | |
925 getButton(IDialogConstants.OK_ID).setEnabled(false); | |
926 errorOccurred = false; | |
927 bool hasFailedOK = false; | |
928 try { | |
929 // Notify all the pages and give them a chance to abort | |
930 Iterator nodes = preferenceManager.getElements(PreferenceManager.PRE_ORDER) | |
931 .iterator(); | |
932 while (nodes.hasNext()) { | |
933 IPreferenceNode node = (IPreferenceNode) nodes.next(); | |
934 IPreferencePage page = node.getPage(); | |
935 if (page !is null) { | |
936 if (!page.performOk()){ | |
937 hasFailedOK = true; | |
938 return; | |
939 } | |
940 } | |
941 } | |
942 } catch (Exception e) { | |
943 handleException(e); | |
944 } finally { | |
945 //Don't bother closing if the OK failed | |
946 if(hasFailedOK){ | |
947 setReturnCode(FAILED); | |
948 getButton(IDialogConstants.OK_ID).setEnabled(true); | |
949 return; | |
950 } | |
951 | |
952 if (!errorOccurred) { | |
953 //Give subclasses the choice to save the state of the | |
954 //preference pages. | |
955 handleSave(); | |
956 } | |
957 setReturnCode(OK); | |
958 close(); | |
959 } | |
960 } | |
961 | |
962 /* | |
963 * (non-Javadoc) | |
964 * | |
965 * @see dwtx.core.runtime.ISafeRunnable#handleException(java.lang.Throwable) | |
966 */ | |
967 public void handleException(Throwable e) { | |
968 errorOccurred = true; | |
969 | |
970 Policy.getLog().log(new Status(IStatus.ERROR, Policy.JFACE, 0, e.toString(), e)); | |
971 | |
972 clearSelectedNode(); | |
973 String message = JFaceResources.getString("SafeRunnable.errorMessage"); //$NON-NLS-1$ | |
974 MessageDialog.openError(getShell(), JFaceResources.getString("Error"), message); //$NON-NLS-1$ | |
975 | |
976 } | |
977 }); | |
978 } | |
979 | |
980 /** | |
981 * Selects the page determined by <code>lastSuccessfulNode</code> in the | |
982 * page hierarchy. | |
983 */ | |
984 void selectCurrentPageAgain() { | |
985 if (lastSuccessfulNode is null) { | |
986 return; | |
987 } | |
988 getTreeViewer().setSelection(new StructuredSelection(lastSuccessfulNode)); | |
989 currentPage.setVisible(true); | |
990 } | |
991 | |
992 /** | |
993 * Selects the saved item in the tree of preference pages. If it cannot do | |
994 * this it saves the first one. | |
995 */ | |
996 protected void selectSavedItem() { | |
997 IPreferenceNode node = findNodeMatching(getSelectedNodePreference()); | |
998 if (node is null) { | |
999 IPreferenceNode[] nodes = preferenceManager.getRootSubNodes(); | |
1000 ViewerFilter[] filters = getTreeViewer().getFilters(); | |
1001 for (int i = 0; i < nodes.length; i++) { | |
1002 IPreferenceNode selectedNode = nodes[i]; | |
1003 // See if it passes all filters | |
1004 for (int j = 0; j < filters.length; j++) { | |
1005 if (!filters[j].select(this.treeViewer, preferenceManager | |
1006 .getRoot(), selectedNode)) { | |
1007 selectedNode = null; | |
1008 break; | |
1009 } | |
1010 } | |
1011 // if it passes all filters select it | |
1012 if (selectedNode !is null) { | |
1013 node = selectedNode; | |
1014 break; | |
1015 } | |
1016 } | |
1017 } | |
1018 if (node !is null) { | |
1019 getTreeViewer().setSelection(new StructuredSelection(node), true); | |
1020 // Keep focus in tree. See bugs 2692, 2621, and 6775. | |
1021 getTreeViewer().getControl().setFocus(); | |
1022 } | |
1023 } | |
1024 | |
1025 /** | |
1026 * Display the given error message. The currently displayed message is saved | |
1027 * and will be redisplayed when the error message is set to | |
1028 * <code>null</code>. | |
1029 * | |
1030 * @param newErrorMessage | |
1031 * the errorMessage to display or <code>null</code> | |
1032 */ | |
1033 public void setErrorMessage(String newErrorMessage) { | |
1034 if (newErrorMessage is null) { | |
1035 messageArea.clearErrorMessage(); | |
1036 } else { | |
1037 messageArea.updateText(newErrorMessage, IMessageProvider.ERROR); | |
1038 } | |
1039 } | |
1040 | |
1041 /** | |
1042 * Save the last known tree width. | |
1043 * | |
1044 * @param width | |
1045 * the width. | |
1046 */ | |
1047 private void setLastTreeWidth(int width) { | |
1048 lastTreeWidth = width; | |
1049 } | |
1050 | |
1051 /** | |
1052 * Set the message text. If the message line currently displays an error, | |
1053 * the message is stored and will be shown after a call to clearErrorMessage | |
1054 * <p> | |
1055 * Shortcut for <code>setMessage(newMessage, NONE)</code> | |
1056 * </p> | |
1057 * | |
1058 * @param newMessage | |
1059 * the message, or <code>null</code> to clear the message | |
1060 */ | |
1061 public void setMessage(String newMessage) { | |
1062 setMessage(newMessage, IMessageProvider.NONE); | |
1063 } | |
1064 | |
1065 /** | |
1066 * Sets the message for this dialog with an indication of what type of | |
1067 * message it is. | |
1068 * <p> | |
1069 * The valid message types are one of <code>NONE</code>, | |
1070 * <code>INFORMATION</code>,<code>WARNING</code>, or | |
1071 * <code>ERROR</code>. | |
1072 * </p> | |
1073 * <p> | |
1074 * Note that for backward compatibility, a message of type | |
1075 * <code>ERROR</code> is different than an error message (set using | |
1076 * <code>setErrorMessage</code>). An error message overrides the current | |
1077 * message until the error message is cleared. This method replaces the | |
1078 * current message and does not affect the error message. | |
1079 * </p> | |
1080 * | |
1081 * @param newMessage | |
1082 * the message, or <code>null</code> to clear the message | |
1083 * @param newType | |
1084 * the message type | |
1085 * @since 2.0 | |
1086 */ | |
1087 public void setMessage(String newMessage, int newType) { | |
1088 messageArea.updateText(newMessage, newType); | |
1089 } | |
1090 | |
1091 /** | |
1092 * Sets the minimum page size. | |
1093 * | |
1094 * @param minWidth | |
1095 * the minimum page width | |
1096 * @param minHeight | |
1097 * the minimum page height | |
1098 * @see #setMinimumPageSize(Point) | |
1099 */ | |
1100 public void setMinimumPageSize(int minWidth, int minHeight) { | |
1101 minimumPageSize.x = minWidth; | |
1102 minimumPageSize.y = minHeight; | |
1103 } | |
1104 | |
1105 /** | |
1106 * Sets the minimum page size. | |
1107 * | |
1108 * @param size | |
1109 * the page size encoded as <code>new Point(width,height)</code> | |
1110 * @see #setMinimumPageSize(int,int) | |
1111 */ | |
1112 public void setMinimumPageSize(Point size) { | |
1113 minimumPageSize.x = size.x; | |
1114 minimumPageSize.y = size.y; | |
1115 } | |
1116 | |
1117 /** | |
1118 * Sets the preference store for this preference dialog. | |
1119 * | |
1120 * @param store | |
1121 * the preference store | |
1122 * @see #getPreferenceStore | |
1123 */ | |
1124 public void setPreferenceStore(IPreferenceStore store) { | |
1125 Assert.isNotNull(store); | |
1126 preferenceStore = store; | |
1127 } | |
1128 | |
1129 /** | |
1130 * Save the currently selected node. | |
1131 */ | |
1132 private void setSelectedNode() { | |
1133 String storeValue = null; | |
1134 IStructuredSelection selection = (IStructuredSelection) getTreeViewer().getSelection(); | |
1135 if (selection.size() is 1) { | |
1136 IPreferenceNode node = (IPreferenceNode) selection.getFirstElement(); | |
1137 storeValue = node.getId(); | |
1138 } | |
1139 setSelectedNodePreference(storeValue); | |
1140 } | |
1141 | |
1142 /** | |
1143 * Sets the name of the selected item preference. Public equivalent to | |
1144 * <code>setSelectedNodePreference</code>. | |
1145 * | |
1146 * @param pageId | |
1147 * The identifier for the page | |
1148 * @since 3.0 | |
1149 */ | |
1150 public void setSelectedNode(String pageId) { | |
1151 setSelectedNodePreference(pageId); | |
1152 } | |
1153 | |
1154 /** | |
1155 * Sets the name of the selected item preference. | |
1156 * | |
1157 * @param pageId | |
1158 * The identifier for the page | |
1159 */ | |
1160 protected void setSelectedNodePreference(String pageId) { | |
1161 lastPreferenceId = pageId; | |
1162 } | |
1163 | |
1164 /** | |
1165 * Changes the shell size to the given size, ensuring that it is no larger | |
1166 * than the display bounds. | |
1167 * | |
1168 * @param width | |
1169 * the shell width | |
1170 * @param height | |
1171 * the shell height | |
1172 */ | |
1173 private void setShellSize(int width, int height) { | |
1174 Rectangle preferred = getShell().getBounds(); | |
1175 preferred.width = width; | |
1176 preferred.height = height; | |
1177 getShell().setBounds(getConstrainedShellBounds(preferred)); | |
1178 } | |
1179 | |
1180 /** | |
1181 * Shows the preference page corresponding to the given preference node. | |
1182 * Does nothing if that page is already current. | |
1183 * | |
1184 * @param node | |
1185 * the preference node, or <code>null</code> if none | |
1186 * @return <code>true</code> if the page flip was successful, and | |
1187 * <code>false</code> is unsuccessful | |
1188 */ | |
1189 protected bool showPage(IPreferenceNode node) { | |
1190 if (node is null) { | |
1191 return false; | |
1192 } | |
1193 // Create the page if nessessary | |
1194 if (node.getPage() is null) { | |
1195 createPage(node); | |
1196 } | |
1197 if (node.getPage() is null) { | |
1198 return false; | |
1199 } | |
1200 IPreferencePage newPage = getPage(node); | |
1201 if (newPage is currentPage) { | |
1202 return true; | |
1203 } | |
1204 if (currentPage !is null) { | |
1205 if (!currentPage.okToLeave()) { | |
1206 return false; | |
1207 } | |
1208 } | |
1209 IPreferencePage oldPage = currentPage; | |
1210 currentPage = newPage; | |
1211 // Set the new page's container | |
1212 currentPage.setContainer(this); | |
1213 // Ensure that the page control has been created | |
1214 // (this allows lazy page control creation) | |
1215 if (currentPage.getControl() is null) { | |
1216 final bool[] failed = { false }; | |
1217 SafeRunnable.run(new ISafeRunnable() { | |
1218 public void handleException(Throwable e) { | |
1219 failed[0] = true; | |
1220 } | |
1221 | |
1222 public void run() { | |
1223 createPageControl(currentPage, pageContainer); | |
1224 } | |
1225 }); | |
1226 if (failed[0]) { | |
1227 return false; | |
1228 } | |
1229 // the page is responsible for ensuring the created control is | |
1230 // accessable | |
1231 // via getControl. | |
1232 Assert.isNotNull(currentPage.getControl()); | |
1233 } | |
1234 // Force calculation of the page's description label because | |
1235 // label can be wrapped. | |
1236 final Point[] size = new Point[1]; | |
1237 final Point failed = new Point(-1, -1); | |
1238 SafeRunnable.run(new ISafeRunnable() { | |
1239 public void handleException(Throwable e) { | |
1240 size[0] = failed; | |
1241 } | |
1242 | |
1243 public void run() { | |
1244 size[0] = currentPage.computeSize(); | |
1245 } | |
1246 }); | |
1247 if (size[0].equals(failed)) { | |
1248 return false; | |
1249 } | |
1250 Point contentSize = size[0]; | |
1251 // Do we need resizing. Computation not needed if the | |
1252 // first page is inserted since computing the dialog's | |
1253 // size is done by calling dialog.open(). | |
1254 // Also prevent auto resize if the user has manually resized | |
1255 Shell shell = getShell(); | |
1256 Point shellSize = shell.getSize(); | |
1257 if (oldPage !is null) { | |
1258 Rectangle rect = pageContainer.getClientArea(); | |
1259 Point containerSize = new Point(rect.width, rect.height); | |
1260 int hdiff = contentSize.x - containerSize.x; | |
1261 int vdiff = contentSize.y - containerSize.y; | |
1262 if ((hdiff > 0 || vdiff > 0) && shellSize.equals(lastShellSize)) { | |
1263 hdiff = Math.max(0, hdiff); | |
1264 vdiff = Math.max(0, vdiff); | |
1265 setShellSize(shellSize.x + hdiff, shellSize.y + vdiff); | |
1266 lastShellSize = shell.getSize(); | |
1267 if (currentPage.getControl().getSize().x is 0) { | |
1268 currentPage.getControl().setSize(containerSize); | |
1269 } | |
1270 | |
1271 } else { | |
1272 currentPage.setSize(containerSize); | |
1273 } | |
1274 } | |
1275 | |
1276 scrolled.setMinSize(contentSize); | |
1277 // Ensure that all other pages are invisible | |
1278 // (including ones that triggered an exception during | |
1279 // their creation). | |
1280 Control[] children = pageContainer.getChildren(); | |
1281 Control currentControl = currentPage.getControl(); | |
1282 for (int i = 0; i < children.length; i++) { | |
1283 if (children[i] !is currentControl) { | |
1284 children[i].setVisible(false); | |
1285 } | |
1286 } | |
1287 // Make the new page visible | |
1288 currentPage.setVisible(true); | |
1289 if (oldPage !is null) { | |
1290 oldPage.setVisible(false); | |
1291 } | |
1292 // update the dialog controls | |
1293 update(); | |
1294 return true; | |
1295 } | |
1296 | |
1297 /** | |
1298 * Create the page for the node. | |
1299 * @param node | |
1300 * | |
1301 * @since 3.1 | |
1302 */ | |
1303 protected void createPage(IPreferenceNode node) { | |
1304 node.createPage(); | |
1305 } | |
1306 | |
1307 /** | |
1308 * Get the page for the node. | |
1309 * @param node | |
1310 * @return IPreferencePage | |
1311 * | |
1312 * @since 3.1 | |
1313 */ | |
1314 protected IPreferencePage getPage(IPreferenceNode node) { | |
1315 return node.getPage(); | |
1316 } | |
1317 | |
1318 /** | |
1319 * Shows the "Page Flipping abort" dialog. | |
1320 */ | |
1321 void showPageFlippingAbortDialog() { | |
1322 MessageDialog.openError(getShell(), JFaceResources | |
1323 .getString("AbortPageFlippingDialog.title"), //$NON-NLS-1$ | |
1324 JFaceResources.getString("AbortPageFlippingDialog.message")); //$NON-NLS-1$ | |
1325 } | |
1326 | |
1327 /** | |
1328 * Updates this dialog's controls to reflect the current page. | |
1329 */ | |
1330 protected void update() { | |
1331 // Update the title bar | |
1332 updateTitle(); | |
1333 // Update the message line | |
1334 updateMessage(); | |
1335 // Update the buttons | |
1336 updateButtons(); | |
1337 //Saved the selected node in the preferences | |
1338 setSelectedNode(); | |
1339 firePageChanged(new PageChangedEvent(this, getCurrentPage())); | |
1340 } | |
1341 | |
1342 /* | |
1343 * (non-Javadoc) | |
1344 * | |
1345 * @see dwtx.jface.preference.IPreferencePageContainer#updateButtons() | |
1346 */ | |
1347 public void updateButtons() { | |
1348 okButton.setEnabled(isCurrentPageValid()); | |
1349 } | |
1350 | |
1351 /* | |
1352 * (non-Javadoc) | |
1353 * | |
1354 * @see dwtx.jface.preference.IPreferencePageContainer#updateMessage() | |
1355 */ | |
1356 public void updateMessage() { | |
1357 String message = null; | |
1358 String errorMessage = null; | |
1359 if(currentPage !is null){ | |
1360 message = currentPage.getMessage(); | |
1361 errorMessage = currentPage.getErrorMessage(); | |
1362 } | |
1363 int messageType = IMessageProvider.NONE; | |
1364 if (message !is null && currentPage instanceof IMessageProvider) { | |
1365 messageType = ((IMessageProvider) currentPage).getMessageType(); | |
1366 } | |
1367 | |
1368 if (errorMessage is null){ | |
1369 if (showingError) { | |
1370 // we were previously showing an error | |
1371 showingError = false; | |
1372 } | |
1373 } | |
1374 else { | |
1375 message = errorMessage; | |
1376 messageType = IMessageProvider.ERROR; | |
1377 if (!showingError) { | |
1378 // we were not previously showing an error | |
1379 showingError = true; | |
1380 } | |
1381 } | |
1382 messageArea.updateText(message,messageType); | |
1383 } | |
1384 | |
1385 /* | |
1386 * (non-Javadoc) | |
1387 * | |
1388 * @see dwtx.jface.preference.IPreferencePageContainer#updateTitle() | |
1389 */ | |
1390 public void updateTitle() { | |
1391 if(currentPage is null) { | |
1392 return; | |
1393 } | |
1394 messageArea.showTitle(currentPage.getTitle(), currentPage.getImage()); | |
1395 } | |
1396 | |
1397 /** | |
1398 * Update the tree to use the specified <code>Font</code>. | |
1399 * | |
1400 * @param dialogFont | |
1401 * the <code>Font</code> to use. | |
1402 * @since 3.0 | |
1403 */ | |
1404 protected void updateTreeFont(Font dialogFont) { | |
1405 getTreeViewer().getControl().setFont(dialogFont); | |
1406 } | |
1407 | |
1408 /** | |
1409 * Returns the currentPage. | |
1410 * @return IPreferencePage | |
1411 * @since 3.1 | |
1412 */ | |
1413 protected IPreferencePage getCurrentPage() { | |
1414 return currentPage; | |
1415 } | |
1416 | |
1417 /** | |
1418 * Sets the current page. | |
1419 * @param currentPage | |
1420 * | |
1421 * @since 3.1 | |
1422 */ | |
1423 protected void setCurrentPage(IPreferencePage currentPage) { | |
1424 this.currentPage = currentPage; | |
1425 } | |
1426 | |
1427 /** | |
1428 * Set the treeViewer. | |
1429 * @param treeViewer | |
1430 * | |
1431 * @since 3.1 | |
1432 */ | |
1433 protected void setTreeViewer(TreeViewer treeViewer) { | |
1434 this.treeViewer = treeViewer; | |
1435 } | |
1436 | |
1437 /** | |
1438 * Get the composite that is showing the page. | |
1439 * | |
1440 * @return Composite. | |
1441 * | |
1442 * @since 3.1 | |
1443 */ | |
1444 protected Composite getPageContainer() { | |
1445 return this.pageContainer; | |
1446 } | |
1447 | |
1448 /** | |
1449 * Set the composite that is showing the page. | |
1450 * @param pageContainer Composite | |
1451 * | |
1452 * @since 3.1 | |
1453 */ | |
1454 protected void setPageContainer(Composite pageContainer) { | |
1455 this.pageContainer = pageContainer; | |
1456 } | |
1457 /** | |
1458 * Create the page control for the supplied page. | |
1459 * | |
1460 * @param page - the preference page to be shown | |
1461 * @param parent - the composite to parent the page | |
1462 * | |
1463 * @since 3.1 | |
1464 */ | |
1465 protected void createPageControl(IPreferencePage page, Composite parent) { | |
1466 page.createControl(parent); | |
1467 } | |
1468 | |
1469 /** | |
1470 * @see dwtx.jface.dialogs.IPageChangeProvider#getSelectedPage() | |
1471 * | |
1472 * @since 3.1 | |
1473 */ | |
1474 public Object getSelectedPage() { | |
1475 return getCurrentPage(); | |
1476 } | |
1477 | |
1478 /** | |
1479 * @see dwtx.jface.dialogs.IPageChangeProvider#addPageChangedListener(dwtx.jface.dialogs.IPageChangedListener) | |
1480 * @since 3.1 | |
1481 */ | |
1482 public void addPageChangedListener(IPageChangedListener listener) { | |
1483 pageChangedListeners.add(listener); | |
1484 } | |
1485 | |
1486 /** | |
1487 * @see dwtx.jface.dialogs.IPageChangeProvider#removePageChangedListener(dwtx.jface.dialogs.IPageChangedListener) | |
1488 * @since 3.1 | |
1489 */ | |
1490 public void removePageChangedListener(IPageChangedListener listener) { | |
1491 pageChangedListeners.remove(listener); | |
1492 | |
1493 } | |
1494 | |
1495 /** | |
1496 * Notifies any selection changed listeners that the selected page | |
1497 * has changed. | |
1498 * Only listeners registered at the time this method is called are notified. | |
1499 * | |
1500 * @param event a selection changed event | |
1501 * | |
1502 * @see IPageChangedListener#pageChanged | |
1503 * | |
1504 * @since 3.1 | |
1505 */ | |
1506 protected void firePageChanged(final PageChangedEvent event) { | |
1507 Object[] listeners = pageChangedListeners.getListeners(); | |
1508 for (int i = 0; i < listeners.length; i++) { | |
1509 final IPageChangedListener l = (IPageChangedListener) listeners[i]; | |
1510 SafeRunnable.run(new SafeRunnable() { | |
1511 public void run() { | |
1512 l.pageChanged(event); | |
1513 } | |
1514 }); | |
1515 } | |
1516 } | |
1517 } | |
1518 ++/ |