Mercurial > projects > dwt-addons
annotate dwtx/jface/wizard/WizardDialog.d @ 104:04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
These new wrappers now use the tango.util.containers instead of the tango.util.collections.
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 07 Aug 2008 15:01:33 +0200 |
parents | 4878bef4a38e |
children | a521c486e142 |
rev | line source |
---|---|
8 | 1 /******************************************************************************* |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
2 * Copyright (c) 2000, 2008 IBM Corporation and others. |
8 | 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 * Chris Gross (schtoo@schtoo.com) - patch for bug 16179 | |
11 * Port to the D programming language: | |
12 * Frank Benoit <benoit@tionex.de> | |
13 *******************************************************************************/ | |
14 module dwtx.jface.wizard.WizardDialog; | |
15 | |
35 | 16 import dwtx.jface.wizard.IWizardContainer2; |
17 import dwtx.jface.wizard.IWizard; | |
18 import dwtx.jface.wizard.IWizardPage; | |
19 import dwtx.jface.wizard.ProgressMonitorPart; | |
8 | 20 |
35 | 21 // import java.lang.reflect.InvocationTargetException; |
22 // import java.util.HashMap; | |
23 // import java.util.Map; | |
8 | 24 |
25 import dwt.DWT; | |
26 import dwt.custom.BusyIndicator; | |
27 import dwt.events.HelpEvent; | |
28 import dwt.events.HelpListener; | |
29 import dwt.events.SelectionAdapter; | |
30 import dwt.events.SelectionEvent; | |
31 import dwt.graphics.Cursor; | |
32 import dwt.graphics.Point; | |
33 import dwt.graphics.Rectangle; | |
34 import dwt.layout.GridData; | |
35 import dwt.layout.GridLayout; | |
36 import dwt.widgets.Button; | |
37 import dwt.widgets.Composite; | |
38 import dwt.widgets.Control; | |
39 import dwt.widgets.Display; | |
40 import dwt.widgets.Label; | |
41 import dwt.widgets.Layout; | |
42 import dwt.widgets.Shell; | |
43 import dwtx.core.runtime.Assert; | |
44 import dwtx.core.runtime.IProgressMonitor; | |
45 import dwtx.core.runtime.IStatus; | |
46 import dwtx.core.runtime.ListenerList; | |
47 import dwtx.jface.dialogs.ControlEnableState; | |
48 import dwtx.jface.dialogs.IDialogConstants; | |
49 import dwtx.jface.dialogs.IMessageProvider; | |
50 import dwtx.jface.dialogs.IPageChangeProvider; | |
51 import dwtx.jface.dialogs.IPageChangedListener; | |
52 import dwtx.jface.dialogs.IPageChangingListener; | |
53 import dwtx.jface.dialogs.MessageDialog; | |
54 import dwtx.jface.dialogs.PageChangedEvent; | |
55 import dwtx.jface.dialogs.PageChangingEvent; | |
56 import dwtx.jface.dialogs.TitleAreaDialog; | |
57 import dwtx.jface.operation.IRunnableWithProgress; | |
58 import dwtx.jface.operation.ModalContext; | |
59 import dwtx.jface.resource.JFaceResources; | |
60 import dwtx.jface.util.SafeRunnable; | |
61 | |
35 | 62 import dwt.dwthelper.utils; |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
63 import dwtx.dwtxhelper.Collection; |
35 | 64 import dwt.dwthelper.Runnable; |
65 | |
8 | 66 /** |
67 * A dialog to show a wizard to the end user. | |
68 * <p> | |
69 * In typical usage, the client instantiates this class with a particular | |
70 * wizard. The dialog serves as the wizard container and orchestrates the | |
71 * presentation of its pages. | |
72 * <p> | |
73 * The standard layout is roughly as follows: it has an area at the top | |
74 * containing both the wizard's title, description, and image; the actual wizard | |
75 * page appears in the middle; below that is a progress indicator (which is made | |
76 * visible if needed); and at the bottom of the page is message line and a | |
77 * button bar containing Help, Next, Back, Finish, and Cancel buttons (or some | |
78 * subset). | |
79 * </p> | |
80 * <p> | |
81 * Clients may subclass <code>WizardDialog</code>, although this is rarely | |
82 * required. | |
83 * </p> | |
84 */ | |
35 | 85 public class WizardDialog : TitleAreaDialog, IWizardContainer2, |
8 | 86 IPageChangeProvider { |
87 /** | |
88 * Image registry key for error message image (value | |
89 * <code>"dialog_title_error_image"</code>). | |
90 */ | |
35 | 91 public static const String WIZ_IMG_ERROR = "dialog_title_error_image"; //$NON-NLS-1$ |
8 | 92 |
93 // The wizard the dialog is currently showing. | |
94 private IWizard wizard; | |
95 | |
96 // Wizards to dispose | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
97 private ArrayList createdWizards; |
8 | 98 |
99 // Current nested wizards | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
100 private ArrayList nestedWizards; |
8 | 101 |
102 // The currently displayed page. | |
103 private IWizardPage currentPage = null; | |
104 | |
105 // The number of long running operation executed from the dialog. | |
106 private long activeRunningOperations = 0; | |
107 | |
108 // The current page message and description | |
109 private String pageMessage; | |
110 | |
111 private int pageMessageType = IMessageProvider.NONE; | |
112 | |
113 private String pageDescription; | |
114 | |
115 // The progress monitor | |
116 private ProgressMonitorPart progressMonitorPart; | |
117 | |
118 private Cursor waitCursor; | |
119 | |
120 private Cursor arrowCursor; | |
121 | |
122 private MessageDialog windowClosingDialog; | |
123 | |
124 // Navigation buttons | |
125 private Button backButton; | |
126 | |
127 private Button nextButton; | |
128 | |
129 private Button finishButton; | |
130 | |
131 private Button cancelButton; | |
132 | |
133 private Button helpButton; | |
134 | |
135 private SelectionAdapter cancelListener; | |
136 | |
137 private bool isMovingToPreviousPage = false; | |
138 | |
139 private Composite pageContainer; | |
140 | |
35 | 141 private PageContainerFillLayout pageContainerLayout; |
8 | 142 |
143 private int pageWidth = DWT.DEFAULT; | |
144 | |
145 private int pageHeight = DWT.DEFAULT; | |
146 | |
35 | 147 private static const String FOCUS_CONTROL = "focusControl"; //$NON-NLS-1$ |
8 | 148 |
149 private bool lockedUI = false; | |
150 | |
35 | 151 private ListenerList pageChangedListeners; |
8 | 152 |
35 | 153 private ListenerList pageChangingListeners; |
8 | 154 |
155 /** | |
156 * A layout for a container which includes several pages, like a notebook, | |
157 * wizard, or preference dialog. The size computed by this layout is the | |
158 * maximum width and height of all pages currently inserted into the | |
159 * container. | |
160 */ | |
35 | 161 protected class PageContainerFillLayout : Layout { |
8 | 162 /** |
163 * The margin width; <code>5</code> pixels by default. | |
164 */ | |
165 public int marginWidth = 5; | |
166 | |
167 /** | |
168 * The margin height; <code>5</code> pixels by default. | |
169 */ | |
170 public int marginHeight = 5; | |
171 | |
172 /** | |
173 * The minimum width; <code>0</code> pixels by default. | |
174 */ | |
175 public int minimumWidth = 0; | |
176 | |
177 /** | |
178 * The minimum height; <code>0</code> pixels by default. | |
179 */ | |
180 public int minimumHeight = 0; | |
181 | |
182 /** | |
183 * Creates new layout object. | |
184 * | |
185 * @param mw | |
186 * the margin width | |
187 * @param mh | |
188 * the margin height | |
189 * @param minW | |
190 * the minimum width | |
191 * @param minH | |
192 * the minimum height | |
193 */ | |
35 | 194 public this(int mw, int mh, int minW, int minH) { |
195 pageContainerLayout = new PageContainerFillLayout( 5, 5, 300, 225); | |
8 | 196 marginWidth = mw; |
197 marginHeight = mh; | |
198 minimumWidth = minW; | |
199 minimumHeight = minH; | |
200 } | |
201 | |
202 /* | |
203 * (non-Javadoc) Method declared on Layout. | |
204 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
205 public override Point computeSize(Composite composite, int wHint, int hHint, |
8 | 206 bool force) { |
207 if (wHint !is DWT.DEFAULT && hHint !is DWT.DEFAULT) { | |
208 return new Point(wHint, hHint); | |
209 } | |
210 Point result = null; | |
211 Control[] children = composite.getChildren(); | |
212 if (children.length > 0) { | |
213 result = new Point(0, 0); | |
214 for (int i = 0; i < children.length; i++) { | |
215 Point cp = children[i].computeSize(wHint, hHint, force); | |
216 result.x = Math.max(result.x, cp.x); | |
217 result.y = Math.max(result.y, cp.y); | |
218 } | |
219 result.x = result.x + 2 * marginWidth; | |
220 result.y = result.y + 2 * marginHeight; | |
221 } else { | |
222 Rectangle rect = composite.getClientArea(); | |
223 result = new Point(rect.width, rect.height); | |
224 } | |
225 result.x = Math.max(result.x, minimumWidth); | |
226 result.y = Math.max(result.y, minimumHeight); | |
227 if (wHint !is DWT.DEFAULT) { | |
228 result.x = wHint; | |
229 } | |
230 if (hHint !is DWT.DEFAULT) { | |
231 result.y = hHint; | |
232 } | |
233 return result; | |
234 } | |
235 | |
236 /** | |
237 * Returns the client area for the given composite according to this | |
238 * layout. | |
239 * | |
240 * @param c | |
241 * the composite | |
242 * @return the client area rectangle | |
243 */ | |
244 public Rectangle getClientArea(Composite c) { | |
245 Rectangle rect = c.getClientArea(); | |
246 rect.x = rect.x + marginWidth; | |
247 rect.y = rect.y + marginHeight; | |
248 rect.width = rect.width - 2 * marginWidth; | |
249 rect.height = rect.height - 2 * marginHeight; | |
250 return rect; | |
251 } | |
252 | |
253 /* | |
254 * (non-Javadoc) Method declared on Layout. | |
255 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
256 public override void layout(Composite composite, bool force) { |
8 | 257 Rectangle rect = getClientArea(composite); |
258 Control[] children = composite.getChildren(); | |
259 for (int i = 0; i < children.length; i++) { | |
260 children[i].setBounds(rect); | |
261 } | |
262 } | |
263 | |
264 /** | |
265 * Lays outs the page according to this layout. | |
266 * | |
267 * @param w | |
268 * the control | |
269 */ | |
270 public void layoutPage(Control w) { | |
271 w.setBounds(getClientArea(w.getParent())); | |
272 } | |
273 | |
274 /** | |
275 * Sets the location of the page so that its origin is in the upper left | |
276 * corner. | |
277 * | |
278 * @param w | |
279 * the control | |
280 */ | |
281 public void setPageLocation(Control w) { | |
282 w.setLocation(marginWidth, marginHeight); | |
283 } | |
284 } | |
285 | |
286 /** | |
287 * Creates a new wizard dialog for the given wizard. | |
288 * | |
289 * @param parentShell | |
290 * the parent shell | |
291 * @param newWizard | |
292 * the wizard this dialog is working on | |
293 */ | |
35 | 294 public this(Shell parentShell, IWizard newWizard) { |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
295 createdWizards = new ArrayList(); |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
296 nestedWizards = new ArrayList(); |
35 | 297 pageChangedListeners = new ListenerList(); |
298 pageChangingListeners = new ListenerList(); | |
299 | |
8 | 300 super(parentShell); |
301 setShellStyle(DWT.CLOSE | DWT.MAX | DWT.TITLE | DWT.BORDER | |
302 | DWT.APPLICATION_MODAL | DWT.RESIZE | getDefaultOrientation()); | |
303 setWizard(newWizard); | |
304 // since VAJava can't initialize an instance var with an anonymous | |
305 // class outside a constructor we do it here: | |
35 | 306 cancelListener = new class SelectionAdapter { |
8 | 307 public void widgetSelected(SelectionEvent e) { |
308 cancelPressed(); | |
309 } | |
310 }; | |
311 } | |
312 | |
313 /** | |
314 * About to start a long running operation triggered through the wizard. | |
315 * Shows the progress monitor and disables the wizard's buttons and | |
316 * controls. | |
317 * | |
318 * @param enableCancelButton | |
319 * <code>true</code> if the Cancel button should be enabled, | |
320 * and <code>false</code> if it should be disabled | |
321 * @return the saved UI state | |
322 */ | |
323 private Object aboutToStart(bool enableCancelButton) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
324 Map savedState = null; |
8 | 325 if (getShell() !is null) { |
326 // Save focus control | |
327 Control focusControl = getShell().getDisplay().getFocusControl(); | |
328 if (focusControl !is null && focusControl.getShell() !is getShell()) { | |
329 focusControl = null; | |
330 } | |
331 bool needsProgressMonitor = wizard.needsProgressMonitor(); | |
332 cancelButton.removeSelectionListener(cancelListener); | |
333 // Set the busy cursor to all shells. | |
334 Display d = getShell().getDisplay(); | |
335 waitCursor = new Cursor(d, DWT.CURSOR_WAIT); | |
336 setDisplayCursor(waitCursor); | |
337 // Set the arrow cursor to the cancel component. | |
338 arrowCursor = new Cursor(d, DWT.CURSOR_ARROW); | |
339 cancelButton.setCursor(arrowCursor); | |
340 // Deactivate shell | |
341 savedState = saveUIState(needsProgressMonitor && enableCancelButton); | |
342 if (focusControl !is null) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
343 savedState.put(stringcast(FOCUS_CONTROL), focusControl); |
8 | 344 } |
345 // Attach the progress monitor part to the cancel button | |
346 if (needsProgressMonitor) { | |
347 progressMonitorPart.attachToCancelComponent(cancelButton); | |
348 progressMonitorPart.setVisible(true); | |
349 } | |
350 } | |
35 | 351 return cast(Object) savedState; |
8 | 352 } |
353 | |
354 /** | |
355 * The Back button has been pressed. | |
356 */ | |
357 protected void backPressed() { | |
358 IWizardPage page = currentPage.getPreviousPage(); | |
359 if (page is null) { | |
360 // should never happen since we have already visited the page | |
361 return; | |
362 } | |
363 | |
364 // set flag to indicate that we are moving back | |
365 isMovingToPreviousPage = true; | |
366 // show the page | |
367 showPage(page); | |
368 } | |
369 | |
370 /* | |
371 * (non-Javadoc) Method declared on Dialog. | |
372 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
373 protected override void buttonPressed(int buttonId) { |
8 | 374 switch (buttonId) { |
375 case IDialogConstants.HELP_ID: { | |
376 helpPressed(); | |
377 break; | |
378 } | |
379 case IDialogConstants.BACK_ID: { | |
380 backPressed(); | |
381 break; | |
382 } | |
383 case IDialogConstants.NEXT_ID: { | |
384 nextPressed(); | |
385 break; | |
386 } | |
387 case IDialogConstants.FINISH_ID: { | |
388 finishPressed(); | |
389 break; | |
390 } | |
391 // The Cancel button has a listener which calls cancelPressed | |
392 // directly | |
393 } | |
394 } | |
395 | |
396 /** | |
397 * Calculates the difference in size between the given page and the page | |
398 * container. A larger page results in a positive delta. | |
399 * | |
400 * @param page | |
401 * the page | |
402 * @return the size difference encoded as a | |
403 * <code>new Point(deltaWidth,deltaHeight)</code> | |
404 */ | |
405 private Point calculatePageSizeDelta(IWizardPage page) { | |
406 Control pageControl = page.getControl(); | |
407 if (pageControl is null) { | |
408 // control not created yet | |
409 return new Point(0, 0); | |
410 } | |
411 Point contentSize = pageControl.computeSize(DWT.DEFAULT, DWT.DEFAULT, | |
412 true); | |
413 Rectangle rect = pageContainerLayout.getClientArea(pageContainer); | |
414 Point containerSize = new Point(rect.width, rect.height); | |
415 return new Point(Math.max(0, contentSize.x - containerSize.x), Math | |
416 .max(0, contentSize.y - containerSize.y)); | |
417 } | |
418 | |
419 /* | |
420 * (non-Javadoc) Method declared on Dialog. | |
421 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
422 protected override void cancelPressed() { |
8 | 423 if (activeRunningOperations <= 0) { |
424 // Close the dialog. The check whether the dialog can be | |
425 // closed or not is done in <code>okToClose</code>. | |
426 // This ensures that the check is also evaluated when the user | |
427 // presses the window's close button. | |
428 setReturnCode(CANCEL); | |
429 close(); | |
430 } else { | |
431 cancelButton.setEnabled(false); | |
432 } | |
433 } | |
434 | |
435 /* | |
436 * (non-Javadoc) | |
437 * | |
438 * @see dwtx.jface.window.Window#close() | |
439 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
440 public override bool close() { |
8 | 441 if (okToClose()) { |
442 return hardClose(); | |
443 } | |
444 return false; | |
445 } | |
446 | |
447 /* | |
448 * (non-Javadoc) Method declared on Window. | |
449 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
450 protected override void configureShell(Shell newShell) { |
8 | 451 super.configureShell(newShell); |
452 // Register help listener on the shell | |
35 | 453 newShell.addHelpListener(new class HelpListener { |
8 | 454 public void helpRequested(HelpEvent event) { |
455 // call perform help on the current page | |
456 if (currentPage !is null) { | |
457 currentPage.performHelp(); | |
458 } | |
459 } | |
460 }); | |
461 } | |
462 | |
463 /** | |
464 * Creates the buttons for this dialog's button bar. | |
465 * <p> | |
466 * The <code>WizardDialog</code> implementation of this framework method | |
467 * prevents the parent composite's columns from being made equal width in | |
468 * order to remove the margin between the Back and Next buttons. | |
469 * </p> | |
470 * | |
471 * @param parent | |
472 * the parent composite to contain the buttons | |
473 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
474 protected override void createButtonsForButtonBar(Composite parent) { |
35 | 475 (cast(GridLayout) parent.getLayout()).makeColumnsEqualWidth = false; |
8 | 476 if (wizard.isHelpAvailable()) { |
477 helpButton = createButton(parent, IDialogConstants.HELP_ID, | |
478 IDialogConstants.HELP_LABEL, false); | |
479 } | |
480 if (wizard.needsPreviousAndNextButtons()) { | |
481 createPreviousAndNextButtons(parent); | |
482 } | |
483 finishButton = createButton(parent, IDialogConstants.FINISH_ID, | |
484 IDialogConstants.FINISH_LABEL, true); | |
485 cancelButton = createCancelButton(parent); | |
486 } | |
487 | |
488 /* | |
489 * (non-Javadoc) | |
490 * | |
491 * @see dwtx.jface.dialogs.Dialog#setButtonLayoutData(dwt.widgets.Button) | |
492 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
493 protected override void setButtonLayoutData(Button button) { |
8 | 494 GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); |
495 int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); | |
496 | |
497 // On large fonts this can make this dialog huge | |
498 widthHint = Math.min(widthHint, | |
499 button.getDisplay().getBounds().width / 5); | |
500 Point minSize = button.computeSize(DWT.DEFAULT, DWT.DEFAULT, true); | |
501 data.widthHint = Math.max(widthHint, minSize.x); | |
502 | |
503 button.setLayoutData(data); | |
504 } | |
505 | |
506 /** | |
507 * Creates the Cancel button for this wizard dialog. Creates a standard (<code>DWT.PUSH</code>) | |
508 * button and registers for its selection events. Note that the number of | |
509 * columns in the button bar composite is incremented. The Cancel button is | |
510 * created specially to give it a removeable listener. | |
511 * | |
512 * @param parent | |
513 * the parent button bar | |
514 * @return the new Cancel button | |
515 */ | |
516 private Button createCancelButton(Composite parent) { | |
517 // increment the number of columns in the button bar | |
35 | 518 (cast(GridLayout) parent.getLayout()).numColumns++; |
8 | 519 Button button = new Button(parent, DWT.PUSH); |
520 button.setText(IDialogConstants.CANCEL_LABEL); | |
521 setButtonLayoutData(button); | |
522 button.setFont(parent.getFont()); | |
523 button.setData(new Integer(IDialogConstants.CANCEL_ID)); | |
524 button.addSelectionListener(cancelListener); | |
525 return button; | |
526 } | |
527 | |
528 /** | |
529 * Return the cancel button if the id is a the cancel id. | |
530 * | |
531 * @param id | |
532 * the button id | |
533 * @return the button corresponding to the button id | |
534 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
535 protected override Button getButton(int id) { |
8 | 536 if (id is IDialogConstants.CANCEL_ID) { |
537 return cancelButton; | |
538 } | |
539 return super.getButton(id); | |
540 } | |
541 | |
542 /** | |
543 * The <code>WizardDialog</code> implementation of this | |
544 * <code>Window</code> method calls call <code>IWizard.addPages</code> | |
545 * to allow the current wizard to add extra pages, then | |
546 * <code>super.createContents</code> to create the controls. It then calls | |
547 * <code>IWizard.createPageControls</code> to allow the wizard to | |
548 * pre-create their page controls prior to opening, so that the wizard opens | |
549 * to the correct size. And finally it shows the first page. | |
550 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
551 protected override Control createContents(Composite parent) { |
8 | 552 // Allow the wizard to add pages to itself |
553 // Need to call this now so page count is correct | |
554 // for determining if next/previous buttons are needed | |
555 wizard.addPages(); | |
556 Control contents = super.createContents(parent); | |
557 // Allow the wizard pages to precreate their page controls | |
558 createPageControls(); | |
559 // Show the first page | |
560 showStartingPage(); | |
561 return contents; | |
562 } | |
563 | |
564 /* | |
565 * (non-Javadoc) Method declared on Dialog. | |
566 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
567 protected override Control createDialogArea(Composite parent) { |
35 | 568 Composite composite = cast(Composite) super.createDialogArea(parent); |
8 | 569 // Build the Page container |
570 pageContainer = createPageContainer(composite); | |
571 GridData gd = new GridData(GridData.FILL_BOTH); | |
572 gd.widthHint = pageWidth; | |
573 gd.heightHint = pageHeight; | |
574 pageContainer.setLayoutData(gd); | |
575 pageContainer.setFont(parent.getFont()); | |
576 // Insert a progress monitor | |
577 GridLayout pmlayout = new GridLayout(); | |
578 pmlayout.numColumns = 1; | |
579 progressMonitorPart = createProgressMonitorPart(composite, pmlayout); | |
580 GridData gridData = new GridData(GridData.FILL_HORIZONTAL); | |
581 progressMonitorPart.setLayoutData(gridData); | |
582 progressMonitorPart.setVisible(false); | |
583 // Build the separator line | |
584 Label separator = new Label(composite, DWT.HORIZONTAL | DWT.SEPARATOR); | |
585 separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); | |
586 | |
587 applyDialogFont(progressMonitorPart); | |
588 return composite; | |
589 } | |
590 | |
591 /** | |
592 * Create the progress monitor part in the receiver. | |
593 * | |
594 * @param composite | |
595 * @param pmlayout | |
596 * @return ProgressMonitorPart | |
597 */ | |
598 protected ProgressMonitorPart createProgressMonitorPart( | |
599 Composite composite, GridLayout pmlayout) { | |
35 | 600 return new class(composite, pmlayout, DWT.DEFAULT) ProgressMonitorPart { |
601 | |
8 | 602 String currentTask = null; |
603 | |
35 | 604 this(Composite c, Layout l, int s ){ |
605 super(c,l,s); | |
606 } | |
607 | |
8 | 608 /* |
609 * (non-Javadoc) | |
610 * | |
611 * @see dwtx.jface.wizard.ProgressMonitorPart#setBlocked(dwtx.core.runtime.IStatus) | |
612 */ | |
613 public void setBlocked(IStatus reason) { | |
614 super.setBlocked(reason); | |
615 if (!lockedUI) { | |
616 getBlockedHandler().showBlocked(getShell(), this, reason, | |
617 currentTask); | |
618 } | |
619 } | |
620 | |
621 /* | |
622 * (non-Javadoc) | |
623 * | |
624 * @see dwtx.jface.wizard.ProgressMonitorPart#clearBlocked() | |
625 */ | |
626 public void clearBlocked() { | |
627 super.clearBlocked(); | |
628 if (!lockedUI) { | |
629 getBlockedHandler().clearBlocked(); | |
630 } | |
631 } | |
632 | |
633 /* | |
634 * (non-Javadoc) | |
635 * | |
636 * @see dwtx.jface.wizard.ProgressMonitorPart#beginTask(java.lang.String, | |
637 * int) | |
638 */ | |
639 public void beginTask(String name, int totalWork) { | |
640 super.beginTask(name, totalWork); | |
641 currentTask = name; | |
642 } | |
643 | |
644 /* | |
645 * (non-Javadoc) | |
646 * | |
647 * @see dwtx.jface.wizard.ProgressMonitorPart#setTaskName(java.lang.String) | |
648 */ | |
649 public void setTaskName(String name) { | |
650 super.setTaskName(name); | |
651 currentTask = name; | |
652 } | |
653 | |
654 /* | |
655 * (non-Javadoc) | |
656 * | |
657 * @see dwtx.jface.wizard.ProgressMonitorPart#subTask(java.lang.String) | |
658 */ | |
659 public void subTask(String name) { | |
660 super.subTask(name); | |
661 // If we haven't got anything yet use this value for more | |
662 // context | |
663 if (currentTask is null) { | |
664 currentTask = name; | |
665 } | |
666 } | |
667 }; | |
668 } | |
669 | |
670 /** | |
671 * Creates the container that holds all pages. | |
672 * | |
673 * @param parent | |
674 * @return Composite | |
675 */ | |
676 private Composite createPageContainer(Composite parent) { | |
677 Composite result = new Composite(parent, DWT.NULL); | |
678 result.setLayout(pageContainerLayout); | |
679 return result; | |
680 } | |
681 | |
682 /** | |
683 * Allow the wizard's pages to pre-create their page controls. This allows | |
684 * the wizard dialog to open to the correct size. | |
685 */ | |
686 private void createPageControls() { | |
687 // Allow the wizard pages to precreate their page controls | |
688 // This allows the wizard to open to the correct size | |
689 wizard.createPageControls(pageContainer); | |
690 // Ensure that all of the created pages are initially not visible | |
691 IWizardPage[] pages = wizard.getPages(); | |
692 for (int i = 0; i < pages.length; i++) { | |
693 IWizardPage page = pages[i]; | |
694 if (page.getControl() !is null) { | |
695 page.getControl().setVisible(false); | |
696 } | |
697 } | |
698 } | |
699 | |
700 /** | |
701 * Creates the Previous and Next buttons for this wizard dialog. Creates | |
702 * standard (<code>DWT.PUSH</code>) buttons and registers for their | |
703 * selection events. Note that the number of columns in the button bar | |
704 * composite is incremented. These buttons are created specially to prevent | |
705 * any space between them. | |
706 * | |
707 * @param parent | |
708 * the parent button bar | |
709 * @return a composite containing the new buttons | |
710 */ | |
711 private Composite createPreviousAndNextButtons(Composite parent) { | |
712 // increment the number of columns in the button bar | |
35 | 713 (cast(GridLayout) parent.getLayout()).numColumns++; |
8 | 714 Composite composite = new Composite(parent, DWT.NONE); |
715 // create a layout with spacing and margins appropriate for the font | |
716 // size. | |
717 GridLayout layout = new GridLayout(); | |
718 layout.numColumns = 0; // will be incremented by createButton | |
719 layout.marginWidth = 0; | |
720 layout.marginHeight = 0; | |
721 layout.horizontalSpacing = 0; | |
722 layout.verticalSpacing = 0; | |
723 composite.setLayout(layout); | |
724 GridData data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER | |
725 | GridData.VERTICAL_ALIGN_CENTER); | |
726 composite.setLayoutData(data); | |
727 composite.setFont(parent.getFont()); | |
728 backButton = createButton(composite, IDialogConstants.BACK_ID, | |
729 IDialogConstants.BACK_LABEL, false); | |
730 nextButton = createButton(composite, IDialogConstants.NEXT_ID, | |
731 IDialogConstants.NEXT_LABEL, false); | |
732 return composite; | |
733 } | |
734 | |
735 /** | |
736 * Creates and return a new wizard closing dialog without openiong it. | |
737 * | |
738 * @return MessageDalog | |
739 */ | |
740 private MessageDialog createWizardClosingDialog() { | |
741 MessageDialog result = new MessageDialog(getShell(), | |
742 JFaceResources.getString("WizardClosingDialog.title"), //$NON-NLS-1$ | |
743 null, | |
744 JFaceResources.getString("WizardClosingDialog.message"), //$NON-NLS-1$ | |
745 MessageDialog.QUESTION, | |
35 | 746 [ IDialogConstants.OK_LABEL ], 0); |
8 | 747 return result; |
748 } | |
749 | |
750 /** | |
751 * The Finish button has been pressed. | |
752 */ | |
753 protected void finishPressed() { | |
754 // Wizards are added to the nested wizards list in setWizard. | |
755 // This means that the current wizard is always the last wizard in the | |
756 // list. | |
757 // Note that we first call the current wizard directly (to give it a | |
758 // chance to | |
759 // abort, do work, and save state) then call the remaining n-1 wizards | |
760 // in the | |
761 // list (to save state). | |
762 if (wizard.performFinish()) { | |
763 // Call perform finish on outer wizards in the nested chain | |
764 // (to allow them to save state for example) | |
765 for (int i = 0; i < nestedWizards.size() - 1; i++) { | |
35 | 766 (cast(IWizard) nestedWizards.get(i)).performFinish(); |
8 | 767 } |
768 // Hard close the dialog. | |
769 setReturnCode(OK); | |
770 hardClose(); | |
771 } | |
772 } | |
773 | |
774 /* | |
775 * (non-Javadoc) Method declared on IWizardContainer. | |
776 */ | |
777 public IWizardPage getCurrentPage() { | |
778 return currentPage; | |
779 } | |
780 | |
781 /** | |
782 * Returns the progress monitor for this wizard dialog (if it has one). | |
783 * | |
784 * @return the progress monitor, or <code>null</code> if this wizard | |
785 * dialog does not have one | |
786 */ | |
787 protected IProgressMonitor getProgressMonitor() { | |
788 return progressMonitorPart; | |
789 } | |
790 | |
791 /** | |
792 * Returns the wizard this dialog is currently displaying. | |
793 * | |
794 * @return the current wizard | |
795 */ | |
796 protected IWizard getWizard() { | |
797 return wizard; | |
798 } | |
799 | |
800 /** | |
801 * Closes this window. | |
802 * | |
803 * @return <code>true</code> if the window is (or was already) closed, and | |
804 * <code>false</code> if it is still open | |
805 */ | |
806 private bool hardClose() { | |
807 // inform wizards | |
808 for (int i = 0; i < createdWizards.size(); i++) { | |
35 | 809 IWizard createdWizard = cast(IWizard) createdWizards.get(i); |
8 | 810 createdWizard.dispose(); |
811 // Remove this dialog as a parent from the managed wizard. | |
812 // Note that we do this after calling dispose as the wizard or | |
813 // its pages may need access to the container during | |
814 // dispose code | |
815 createdWizard.setContainer(null); | |
816 } | |
817 return super.close(); | |
818 } | |
819 | |
820 /** | |
821 * The Help button has been pressed. | |
822 */ | |
823 protected void helpPressed() { | |
824 if (currentPage !is null) { | |
825 currentPage.performHelp(); | |
826 } | |
827 } | |
828 | |
829 /** | |
830 * The Next button has been pressed. | |
831 */ | |
832 protected void nextPressed() { | |
833 IWizardPage page = currentPage.getNextPage(); | |
834 if (page is null) { | |
835 // something must have happend getting the next page | |
836 return; | |
837 } | |
838 | |
839 // show the next page | |
840 showPage(page); | |
841 } | |
842 | |
843 /** | |
844 * Notifies page changing listeners and returns result of page changing | |
845 * processing to the sender. | |
846 * | |
847 * @param eventType | |
848 * @return <code>true</code> if page changing listener completes | |
849 * successfully, <code>false</code> otherwise | |
850 */ | |
851 private bool doPageChanging(IWizardPage targetPage) { | |
35 | 852 PageChangingEvent e = new PageChangingEvent(this, cast(Object)getCurrentPage(), |
853 cast(Object)targetPage); | |
8 | 854 firePageChanging(e); |
855 // Prevent navigation if necessary | |
856 return e.doit; | |
857 } | |
858 | |
859 /** | |
860 * Checks whether it is alright to close this wizard dialog and performed | |
861 * standard cancel processing. If there is a long running operation in | |
862 * progress, this method posts an alert message saying that the wizard | |
863 * cannot be closed. | |
864 * | |
865 * @return <code>true</code> if it is alright to close this dialog, and | |
866 * <code>false</code> if it is not | |
867 */ | |
868 private bool okToClose() { | |
869 if (activeRunningOperations > 0) { | |
870 synchronized (this) { | |
871 windowClosingDialog = createWizardClosingDialog(); | |
872 } | |
873 windowClosingDialog.open(); | |
874 synchronized (this) { | |
875 windowClosingDialog = null; | |
876 } | |
877 return false; | |
878 } | |
879 return wizard.performCancel(); | |
880 } | |
881 | |
882 /** | |
883 * Restores the enabled/disabled state of the given control. | |
884 * | |
885 * @param w | |
886 * the control | |
887 * @param h | |
888 * the map (key type: <code>String</code>, element type: | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
889 * <code>Boolean</code>) |
8 | 890 * @param key |
891 * the key | |
892 * @see #saveEnableStateAndSet | |
893 */ | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
894 private void restoreEnableState(Control w, Map h, String key) { |
8 | 895 if (w !is null) { |
71 | 896 Boolean b = cast(Boolean) h.get(stringcast(key)); |
8 | 897 if (b !is null) { |
898 w.setEnabled(b.booleanValue()); | |
899 } | |
900 } | |
901 } | |
902 | |
903 /** | |
904 * Restores the enabled/disabled state of the wizard dialog's buttons and | |
905 * the tree of controls for the currently showing page. | |
906 * | |
907 * @param state | |
908 * a map containing the saved state as returned by | |
909 * <code>saveUIState</code> | |
910 * @see #saveUIState | |
911 */ | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
912 private void restoreUIState(Map state) { |
8 | 913 restoreEnableState(backButton, state, "back"); //$NON-NLS-1$ |
914 restoreEnableState(nextButton, state, "next"); //$NON-NLS-1$ | |
915 restoreEnableState(finishButton, state, "finish"); //$NON-NLS-1$ | |
916 restoreEnableState(cancelButton, state, "cancel"); //$NON-NLS-1$ | |
917 restoreEnableState(helpButton, state, "help"); //$NON-NLS-1$ | |
35 | 918 Object pageValue = state.get(stringcast("page")); //$NON-NLS-1$ |
8 | 919 if (pageValue !is null) { |
35 | 920 (cast(ControlEnableState) pageValue).restore(); |
8 | 921 } |
922 } | |
923 | |
924 /** | |
925 * This implementation of IRunnableContext#run(bool, bool, | |
926 * IRunnableWithProgress) blocks until the runnable has been run, regardless | |
927 * of the value of <code>fork</code>. It is recommended that | |
928 * <code>fork</code> is set to true in most cases. If <code>fork</code> | |
929 * is set to <code>false</code>, the runnable will run in the UI thread | |
930 * and it is the runnable's responsibility to call | |
931 * <code>Display.readAndDispatch()</code> to ensure UI responsiveness. | |
932 * | |
933 * UI state is saved prior to executing the long-running operation and is | |
934 * restored after the long-running operation completes executing. Any | |
935 * attempt to change the UI state of the wizard in the long-running | |
936 * operation will be nullified when original UI state is restored. | |
937 * | |
938 */ | |
939 public void run(bool fork, bool cancelable, | |
35 | 940 IRunnableWithProgress runnable) { |
8 | 941 // The operation can only be canceled if it is executed in a separate |
942 // thread. | |
943 // Otherwise the UI is blocked anyway. | |
944 Object state = null; | |
945 if (activeRunningOperations is 0) { | |
946 state = aboutToStart(fork && cancelable); | |
947 } | |
948 activeRunningOperations++; | |
949 try { | |
950 if (!fork) { | |
951 lockedUI = true; | |
952 } | |
953 ModalContext.run(runnable, fork, getProgressMonitor(), getShell() | |
954 .getDisplay()); | |
955 lockedUI = false; | |
956 } finally { | |
957 activeRunningOperations--; | |
958 // Stop if this is the last one | |
959 if (state !is null) { | |
960 stopped(state); | |
961 } | |
962 } | |
963 } | |
964 | |
965 /** | |
966 * Saves the enabled/disabled state of the given control in the given map, | |
967 * which must be modifiable. | |
968 * | |
969 * @param w | |
970 * the control, or <code>null</code> if none | |
971 * @param h | |
972 * the map (key type: <code>String</code>, element type: | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
973 * <code>Boolean</code>) |
8 | 974 * @param key |
975 * the key | |
976 * @param enabled | |
977 * <code>true</code> to enable the control, and | |
978 * <code>false</code> to disable it | |
979 * @see #restoreEnableState(Control, Map, String) | |
980 */ | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
981 private void saveEnableStateAndSet(Control w, Map h, String key, |
8 | 982 bool enabled) { |
983 if (w !is null) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
984 h.put(stringcast(key), w.getEnabled() ? Boolean.TRUE : Boolean.FALSE); |
8 | 985 w.setEnabled(enabled); |
986 } | |
987 } | |
988 | |
989 /** | |
990 * Captures and returns the enabled/disabled state of the wizard dialog's | |
991 * buttons and the tree of controls for the currently showing page. All | |
992 * these controls are disabled in the process, with the possible exception | |
993 * of the Cancel button. | |
994 * | |
995 * @param keepCancelEnabled | |
996 * <code>true</code> if the Cancel button should remain | |
997 * enabled, and <code>false</code> if it should be disabled | |
998 * @return a map containing the saved state suitable for restoring later | |
999 * with <code>restoreUIState</code> | |
1000 * @see #restoreUIState | |
1001 */ | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
1002 private Map saveUIState(bool keepCancelEnabled) { |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
1003 Map savedState = new HashMap(10); |
8 | 1004 saveEnableStateAndSet(backButton, savedState, "back", false); //$NON-NLS-1$ |
1005 saveEnableStateAndSet(nextButton, savedState, "next", false); //$NON-NLS-1$ | |
1006 saveEnableStateAndSet(finishButton, savedState, "finish", false); //$NON-NLS-1$ | |
1007 saveEnableStateAndSet(cancelButton, savedState, | |
1008 "cancel", keepCancelEnabled); //$NON-NLS-1$ | |
1009 saveEnableStateAndSet(helpButton, savedState, "help", false); //$NON-NLS-1$ | |
1010 if (currentPage !is null) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
1011 savedState.put(stringcast("page"), ControlEnableState.disable(currentPage.getControl())); //$NON-NLS-1$ |
8 | 1012 } |
1013 return savedState; | |
1014 } | |
1015 | |
1016 /** | |
1017 * Sets the given cursor for all shells currently active for this window's | |
1018 * display. | |
1019 * | |
1020 * @param c | |
1021 * the cursor | |
1022 */ | |
1023 private void setDisplayCursor(Cursor c) { | |
1024 Shell[] shells = getShell().getDisplay().getShells(); | |
1025 for (int i = 0; i < shells.length; i++) { | |
1026 shells[i].setCursor(c); | |
1027 } | |
1028 } | |
1029 | |
1030 /** | |
1031 * Sets the minimum page size used for the pages. | |
1032 * | |
1033 * @param minWidth | |
1034 * the minimum page width | |
1035 * @param minHeight | |
1036 * the minimum page height | |
1037 * @see #setMinimumPageSize(Point) | |
1038 */ | |
1039 public void setMinimumPageSize(int minWidth, int minHeight) { | |
1040 Assert.isTrue(minWidth >= 0 && minHeight >= 0); | |
1041 pageContainerLayout.minimumWidth = minWidth; | |
1042 pageContainerLayout.minimumHeight = minHeight; | |
1043 } | |
1044 | |
1045 /** | |
1046 * Sets the minimum page size used for the pages. | |
1047 * | |
1048 * @param size | |
1049 * the page size encoded as <code>new Point(width,height)</code> | |
1050 * @see #setMinimumPageSize(int,int) | |
1051 */ | |
1052 public void setMinimumPageSize(Point size) { | |
1053 setMinimumPageSize(size.x, size.y); | |
1054 } | |
1055 | |
1056 /** | |
1057 * Sets the size of all pages. The given size takes precedence over computed | |
1058 * sizes. | |
1059 * | |
1060 * @param width | |
1061 * the page width | |
1062 * @param height | |
1063 * the page height | |
1064 * @see #setPageSize(Point) | |
1065 */ | |
1066 public void setPageSize(int width, int height) { | |
1067 pageWidth = width; | |
1068 pageHeight = height; | |
1069 } | |
1070 | |
1071 /** | |
1072 * Sets the size of all pages. The given size takes precedence over computed | |
1073 * sizes. | |
1074 * | |
1075 * @param size | |
1076 * the page size encoded as <code>new Point(width,height)</code> | |
1077 * @see #setPageSize(int,int) | |
1078 */ | |
1079 public void setPageSize(Point size) { | |
1080 setPageSize(size.x, size.y); | |
1081 } | |
1082 | |
1083 /** | |
1084 * Sets the wizard this dialog is currently displaying. | |
1085 * | |
1086 * @param newWizard | |
1087 * the wizard | |
1088 */ | |
1089 protected void setWizard(IWizard newWizard) { | |
1090 wizard = newWizard; | |
1091 wizard.setContainer(this); | |
35 | 1092 if (!createdWizards.contains(cast(Object)wizard)) { |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
1093 createdWizards.add(cast(Object)wizard); |
8 | 1094 // New wizard so just add it to the end of our nested list |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
1095 nestedWizards.add(cast(Object)wizard); |
8 | 1096 if (pageContainer !is null) { |
1097 // Dialog is already open | |
1098 // Allow the wizard pages to precreate their page controls | |
1099 // This allows the wizard to open to the correct size | |
1100 createPageControls(); | |
1101 // Ensure the dialog is large enough for the wizard | |
1102 updateSizeForWizard(wizard); | |
1103 pageContainer.layout(true); | |
1104 } | |
1105 } else { | |
1106 // We have already seen this wizard, if it is the previous wizard | |
1107 // on the nested list then we assume we have gone back and remove | |
1108 // the last wizard from the list | |
1109 int size = nestedWizards.size(); | |
35 | 1110 if (size >= 2 && nestedWizards.get(size - 2) is cast(Object)wizard) { |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
1111 nestedWizards.remove(size - 1); |
8 | 1112 } else { |
1113 // Assume we are going forward to revisit a wizard | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
1114 nestedWizards.add(cast(Object)wizard); |
8 | 1115 } |
1116 } | |
1117 } | |
1118 | |
1119 /* | |
1120 * (non-Javadoc) Method declared on IWizardContainer. | |
1121 */ | |
1122 public void showPage(IWizardPage page) { | |
1123 if (page is null || page is currentPage) { | |
1124 return; | |
1125 } | |
1126 | |
1127 if (!isMovingToPreviousPage) { | |
1128 // remember my previous page. | |
1129 page.setPreviousPage(currentPage); | |
1130 } else { | |
1131 isMovingToPreviousPage = false; | |
1132 } | |
1133 | |
1134 // If page changing evaluation unsuccessful, do not change the page | |
1135 if (!doPageChanging(page)) | |
1136 return; | |
1137 | |
1138 // Update for the new page in a busy cursor if possible | |
1139 if (getContents() is null) { | |
1140 updateForPage(page); | |
1141 } else { | |
1142 final IWizardPage finalPage = page; | |
35 | 1143 BusyIndicator.showWhile(getContents().getDisplay(), new class Runnable { |
8 | 1144 public void run() { |
1145 updateForPage(finalPage); | |
1146 } | |
1147 }); | |
1148 } | |
1149 } | |
1150 | |
1151 /** | |
1152 * Update the receiver for the new page. | |
1153 * | |
1154 * @param page | |
1155 */ | |
1156 private void updateForPage(IWizardPage page) { | |
1157 // ensure this page belongs to the current wizard | |
1158 if (wizard !is page.getWizard()) { | |
1159 setWizard(page.getWizard()); | |
1160 } | |
1161 // ensure that page control has been created | |
1162 // (this allows lazy page control creation) | |
1163 if (page.getControl() is null) { | |
1164 page.createControl(pageContainer); | |
1165 // the page is responsible for ensuring the created control is | |
1166 // accessable | |
1167 // via getControl. | |
1168 Assert.isNotNull(page.getControl(), JFaceResources.format( | |
1169 JFaceResources.getString("WizardDialog.missingSetControl"), //$NON-NLS-1$ | |
35 | 1170 [ page.getName() ])); |
8 | 1171 // ensure the dialog is large enough for this page |
1172 updateSize(page); | |
1173 } | |
1174 // make the new page visible | |
1175 IWizardPage oldPage = currentPage; | |
1176 currentPage = page; | |
1177 | |
1178 currentPage.setVisible(true); | |
1179 if (oldPage !is null) { | |
1180 oldPage.setVisible(false); | |
1181 } | |
1182 // update the dialog controls | |
1183 update(); | |
1184 } | |
1185 | |
1186 /** | |
1187 * Shows the starting page of the wizard. | |
1188 */ | |
1189 private void showStartingPage() { | |
1190 currentPage = wizard.getStartingPage(); | |
1191 if (currentPage is null) { | |
1192 // something must have happend getting the page | |
1193 return; | |
1194 } | |
1195 // ensure the page control has been created | |
1196 if (currentPage.getControl() is null) { | |
1197 currentPage.createControl(pageContainer); | |
1198 // the page is responsible for ensuring the created control is | |
1199 // accessable | |
1200 // via getControl. | |
1201 Assert.isNotNull(currentPage.getControl()); | |
1202 // we do not need to update the size since the call | |
1203 // to initialize bounds has not been made yet. | |
1204 } | |
1205 // make the new page visible | |
1206 currentPage.setVisible(true); | |
1207 // update the dialog controls | |
1208 update(); | |
1209 } | |
1210 | |
1211 /** | |
1212 * A long running operation triggered through the wizard was stopped either | |
1213 * by user input or by normal end. Hides the progress monitor and restores | |
1214 * the enable state wizard's buttons and controls. | |
1215 * | |
1216 * @param savedState | |
1217 * the saved UI state as returned by <code>aboutToStart</code> | |
1218 * @see #aboutToStart | |
1219 */ | |
1220 private void stopped(Object savedState) { | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
1221 if (getShell() !is null && !getShell().isDisposed()) { |
8 | 1222 if (wizard.needsProgressMonitor()) { |
1223 progressMonitorPart.setVisible(false); | |
1224 progressMonitorPart.removeFromCancelComponent(cancelButton); | |
1225 } | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
1226 Map state = cast(Map) savedState; |
8 | 1227 restoreUIState(state); |
1228 cancelButton.addSelectionListener(cancelListener); | |
1229 setDisplayCursor(null); | |
1230 cancelButton.setCursor(null); | |
1231 waitCursor.dispose(); | |
1232 waitCursor = null; | |
1233 arrowCursor.dispose(); | |
1234 arrowCursor = null; | |
35 | 1235 Control focusControl = cast(Control) state.get(stringcast(FOCUS_CONTROL)); |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
1236 if (focusControl !is null && !focusControl.isDisposed()) { |
8 | 1237 focusControl.setFocus(); |
1238 } | |
1239 } | |
1240 } | |
1241 | |
1242 /** | |
1243 * Updates this dialog's controls to reflect the current page. | |
1244 */ | |
1245 protected void update() { | |
1246 // Update the window title | |
1247 updateWindowTitle(); | |
1248 // Update the title bar | |
1249 updateTitleBar(); | |
1250 // Update the buttons | |
1251 updateButtons(); | |
1252 | |
1253 // Fires the page change event | |
35 | 1254 firePageChanged(new PageChangedEvent(this, cast(Object)getCurrentPage())); |
8 | 1255 } |
1256 | |
1257 /* | |
1258 * (non-Javadoc) Method declared on IWizardContainer. | |
1259 */ | |
1260 public void updateButtons() { | |
1261 bool canFlipToNextPage = false; | |
1262 bool canFinish = wizard.canFinish(); | |
1263 if (backButton !is null) { | |
1264 backButton.setEnabled(currentPage.getPreviousPage() !is null); | |
1265 } | |
1266 if (nextButton !is null) { | |
1267 canFlipToNextPage = currentPage.canFlipToNextPage(); | |
1268 nextButton.setEnabled(canFlipToNextPage); | |
1269 } | |
1270 finishButton.setEnabled(canFinish); | |
1271 // finish is default unless it is diabled and next is enabled | |
1272 if (canFlipToNextPage && !canFinish) { | |
1273 getShell().setDefaultButton(nextButton); | |
1274 } else { | |
1275 getShell().setDefaultButton(finishButton); | |
1276 } | |
1277 } | |
1278 | |
1279 /** | |
1280 * Update the message line with the page's description. | |
1281 * <p> | |
1282 * A discription is shown only if there is no message or error message. | |
1283 * </p> | |
1284 */ | |
1285 private void updateDescriptionMessage() { | |
1286 pageDescription = currentPage.getDescription(); | |
1287 setMessage(pageDescription); | |
1288 } | |
1289 | |
1290 /* | |
1291 * (non-Javadoc) Method declared on IWizardContainer. | |
1292 */ | |
1293 public void updateMessage() { | |
1294 | |
1295 if (currentPage is null) { | |
1296 return; | |
1297 } | |
1298 | |
1299 pageMessage = currentPage.getMessage(); | |
35 | 1300 if (pageMessage !is null && cast(IMessageProvider)currentPage ) { |
1301 pageMessageType = (cast(IMessageProvider) currentPage).getMessageType(); | |
8 | 1302 } else { |
1303 pageMessageType = IMessageProvider.NONE; | |
1304 } | |
1305 if (pageMessage is null) { | |
1306 setMessage(pageDescription); | |
1307 } else { | |
1308 setMessage(pageMessage, pageMessageType); | |
1309 } | |
1310 setErrorMessage(currentPage.getErrorMessage()); | |
1311 } | |
1312 | |
1313 /** | |
1314 * Changes the shell size to the given size, ensuring that it is no larger | |
1315 * than the display bounds. | |
1316 * | |
1317 * @param width | |
1318 * the shell width | |
1319 * @param height | |
1320 * the shell height | |
1321 */ | |
1322 private void setShellSize(int width, int height) { | |
1323 Rectangle size = getShell().getBounds(); | |
1324 size.height = height; | |
1325 size.width = width; | |
1326 getShell().setBounds(getConstrainedShellBounds(size)); | |
1327 } | |
1328 | |
1329 /** | |
1330 * Computes the correct dialog size for the current page and resizes its | |
1331 * shell if nessessary. Also causes the container to refresh its layout. | |
1332 * | |
1333 * @param page | |
1334 * the wizard page to use to resize the dialog | |
1335 * @since 2.0 | |
1336 */ | |
1337 protected void updateSize(IWizardPage page) { | |
1338 if (page is null || page.getControl() is null) { | |
1339 return; | |
1340 } | |
1341 updateSizeForPage(page); | |
1342 pageContainerLayout.layoutPage(page.getControl()); | |
1343 } | |
1344 | |
1345 /* | |
1346 * (non-Javadoc) | |
1347 * | |
1348 * @see dwtx.jface.wizard.IWizardContainer2#updateSize() | |
1349 */ | |
1350 public void updateSize() { | |
1351 updateSize(currentPage); | |
1352 } | |
1353 | |
1354 /** | |
1355 * Computes the correct dialog size for the given page and resizes its shell | |
1356 * if nessessary. | |
1357 * | |
1358 * @param page | |
1359 * the wizard page | |
1360 */ | |
1361 private void updateSizeForPage(IWizardPage page) { | |
1362 // ensure the page container is large enough | |
1363 Point delta = calculatePageSizeDelta(page); | |
1364 if (delta.x > 0 || delta.y > 0) { | |
1365 // increase the size of the shell | |
1366 Shell shell = getShell(); | |
1367 Point shellSize = shell.getSize(); | |
1368 setShellSize(shellSize.x + delta.x, shellSize.y + delta.y); | |
1369 constrainShellSize(); | |
1370 } | |
1371 } | |
1372 | |
1373 /** | |
1374 * Computes the correct dialog size for the given wizard and resizes its | |
1375 * shell if nessessary. | |
1376 * | |
1377 * @param sizingWizard | |
1378 * the wizard | |
1379 */ | |
1380 private void updateSizeForWizard(IWizard sizingWizard) { | |
1381 Point delta = new Point(0, 0); | |
1382 IWizardPage[] pages = sizingWizard.getPages(); | |
1383 for (int i = 0; i < pages.length; i++) { | |
1384 // ensure the page container is large enough | |
1385 Point pageDelta = calculatePageSizeDelta(pages[i]); | |
1386 delta.x = Math.max(delta.x, pageDelta.x); | |
1387 delta.y = Math.max(delta.y, pageDelta.y); | |
1388 } | |
1389 if (delta.x > 0 || delta.y > 0) { | |
1390 // increase the size of the shell | |
1391 Shell shell = getShell(); | |
1392 Point shellSize = shell.getSize(); | |
1393 setShellSize(shellSize.x + delta.x, shellSize.y + delta.y); | |
1394 } | |
1395 } | |
1396 | |
1397 /* | |
1398 * (non-Javadoc) Method declared on IWizardContainer. | |
1399 */ | |
1400 public void updateTitleBar() { | |
1401 String s = null; | |
1402 if (currentPage !is null) { | |
1403 s = currentPage.getTitle(); | |
1404 } | |
1405 if (s is null) { | |
1406 s = ""; //$NON-NLS-1$ | |
1407 } | |
1408 setTitle(s); | |
1409 if (currentPage !is null) { | |
1410 setTitleImage(currentPage.getImage()); | |
1411 updateDescriptionMessage(); | |
1412 } | |
1413 updateMessage(); | |
1414 } | |
1415 | |
1416 /* | |
1417 * (non-Javadoc) Method declared on IWizardContainer. | |
1418 */ | |
1419 public void updateWindowTitle() { | |
1420 if (getShell() is null) { | |
1421 // Not created yet | |
1422 return; | |
1423 } | |
1424 String title = wizard.getWindowTitle(); | |
1425 if (title is null) { | |
1426 title = ""; //$NON-NLS-1$ | |
1427 } | |
1428 getShell().setText(title); | |
1429 } | |
1430 | |
1431 /* | |
1432 * (non-Javadoc) | |
1433 * | |
1434 * @see dwtx.jface.dialogs.IPageChangeProvider#getSelectedPage() | |
1435 */ | |
1436 public Object getSelectedPage() { | |
35 | 1437 return cast(Object)getCurrentPage(); |
8 | 1438 } |
1439 | |
1440 /* | |
1441 * (non-Javadoc) | |
1442 * | |
1443 * @see dwtx.jface.dialog.IPageChangeProvider#addPageChangedListener() | |
1444 */ | |
1445 public void addPageChangedListener(IPageChangedListener listener) { | |
35 | 1446 pageChangedListeners.add(cast(Object)listener); |
8 | 1447 } |
1448 | |
1449 /* | |
1450 * (non-Javadoc) | |
1451 * | |
1452 * @see dwtx.jface.dialog.IPageChangeProvider#removePageChangedListener() | |
1453 */ | |
1454 public void removePageChangedListener(IPageChangedListener listener) { | |
35 | 1455 pageChangedListeners.remove(cast(Object)listener); |
8 | 1456 } |
1457 | |
1458 /** | |
1459 * Notifies any selection changed listeners that the selected page has | |
1460 * changed. Only listeners registered at the time this method is called are | |
1461 * notified. | |
1462 * | |
1463 * @param event | |
1464 * a selection changed event | |
1465 * | |
1466 * @see IPageChangedListener#pageChanged | |
1467 * | |
1468 * @since 3.1 | |
1469 */ | |
35 | 1470 protected void firePageChanged(PageChangedEvent event) { |
8 | 1471 Object[] listeners = pageChangedListeners.getListeners(); |
1472 for (int i = 0; i < listeners.length; ++i) { | |
39 | 1473 SafeRunnable.run(new class(cast(IPageChangedListener) listeners[i],event) SafeRunnable { |
35 | 1474 PageChangedEvent event_; |
1475 IPageChangedListener l; | |
39 | 1476 this(IPageChangedListener a, PageChangedEvent b){ |
1477 l = a; | |
1478 event_=b; | |
35 | 1479 } |
8 | 1480 public void run() { |
35 | 1481 l.pageChanged(event_); |
8 | 1482 } |
1483 }); | |
1484 } | |
1485 } | |
1486 | |
1487 /** | |
1488 * Adds a listener for page changes to the list of page changing listeners | |
1489 * registered for this dialog. Has no effect if an identical listener is | |
1490 * already registered. | |
1491 * | |
1492 * @param listener | |
1493 * a page changing listener | |
1494 * @since 3.3 | |
1495 */ | |
1496 public void addPageChangingListener(IPageChangingListener listener) { | |
35 | 1497 pageChangingListeners.add(cast(Object)listener); |
8 | 1498 } |
1499 | |
1500 /** | |
1501 * Removes the provided page changing listener from the list of page | |
1502 * changing listeners registered for the dialog. | |
1503 * | |
1504 * @param listener | |
1505 * a page changing listener | |
1506 * @since 3.3 | |
1507 */ | |
1508 public void removePageChangingListener(IPageChangingListener listener) { | |
35 | 1509 pageChangingListeners.remove(cast(Object)listener); |
8 | 1510 } |
1511 | |
1512 /** | |
1513 * Notifies any page changing listeners that the currently selected dialog | |
1514 * page is changing. Only listeners registered at the time this method is | |
1515 * called are notified. | |
1516 * | |
1517 * @param event | |
1518 * a selection changing event | |
1519 * | |
1520 * @see IPageChangingListener#handlePageChanging(PageChangingEvent) | |
1521 * @since 3.3 | |
1522 */ | |
35 | 1523 protected void firePageChanging(PageChangingEvent event) { |
8 | 1524 Object[] listeners = pageChangingListeners.getListeners(); |
1525 for (int i = 0; i < listeners.length; ++i) { | |
39 | 1526 SafeRunnable.run(new class(cast(IPageChangingListener) listeners[i],event) SafeRunnable { |
35 | 1527 PageChangingEvent event_; |
1528 IPageChangingListener l; | |
39 | 1529 this(IPageChangingListener a, PageChangingEvent b){ |
1530 l = a; | |
1531 event_=b; | |
35 | 1532 } |
8 | 1533 public void run() { |
35 | 1534 l.handlePageChanging(event_); |
8 | 1535 } |
1536 }); | |
1537 } | |
1538 } | |
1539 } |