1 /********************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others. All rights reserved.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
5 * and is available at http://www.eclipse.org/legal/epl-v10.html Contributors:
6 * IBM Corporation - initial API and implementation
7 ******************************************************************************/
8 package sk.uniba.euromath.editor.wizards;
9 import java.util.ArrayList;
10 import java.util.List;
11 import org.eclipse.core.runtime.IStatus;
12 import org.eclipse.jface.dialogs.IDialogConstants;
13 import org.eclipse.jface.dialogs.IMessageProvider;
14 import org.eclipse.jface.dialogs.IPageChangeProvider;
15 import org.eclipse.jface.dialogs.IPageChangedListener;
16 import org.eclipse.jface.dialogs.MessageDialog;
17 import org.eclipse.jface.dialogs.PageChangedEvent;
18 import org.eclipse.jface.dialogs.TitleAreaDialog;
19 import org.eclipse.jface.util.Assert;
20 import org.eclipse.core.runtime.ListenerList;
21 import org.eclipse.jface.util.SafeRunnable;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.events.SelectionAdapter;
24 import org.eclipse.swt.events.SelectionEvent;
25 import org.eclipse.swt.graphics.Point;
26 import org.eclipse.swt.graphics.Rectangle;
27 import org.eclipse.swt.layout.GridData;
28 import org.eclipse.swt.layout.GridLayout;
29 import org.eclipse.swt.widgets.Button;
30 import org.eclipse.swt.widgets.Composite;
31 import org.eclipse.swt.widgets.Control;
32 import org.eclipse.swt.widgets.Label;
33 import org.eclipse.swt.widgets.Layout;
34 import org.eclipse.swt.widgets.Shell;
35 import sk.uniba.euromath.EuroMath;
36 import sk.uniba.euromath.editor.lang.Messages;
37 import sk.uniba.euromath.editor.widgets.ValidityMessages;
38 import sk.uniba.euromath.tools.JavaTools;
39 import sk.uniba.euromath.tools.StringTools;
40 /***
41 * A dialog to show a wizard to the end user.
42 * <p>
43 * In typical usage, the client instantiates this class with a particular
44 * wizard. The dialog serves as the wizard container and orchestrates the
45 * presentation of its pages.
46 * <p>
47 * The standard layout is roughly as follows: it has an area at the top
48 * containing both the wizard's title, description, and image; the actual wizard
49 * page appears in the middle; below that is a progress indicator (which is made
50 * visible if needed); and at the bottom of the page is message line and a
51 * button bar containing Help, Next, Back, Finish, and Cancel buttons (or some
52 * subset).
53 * </p>
54 * <p>
55 * Wizard is not disposed when the dialog exits.
56 * </p>
57 */
58 public final class WizardDialog extends TitleAreaDialog implements
59 IPageChangeProvider {
60 /***
61 * Image registry key for error message image (value
62 * <code>"dialog_title_error_image"</code>).
63 */
64 public static final String WIZ_IMG_ERROR = "dialog_title_error_image";
65 /***
66 * The wizard the dialog is currently showing.
67 */
68 private final IWizard wizard;
69
70 private Button backButton;
71 private Button nextButton;
72 private Button finishButton;
73 private Button cancelButton;
74 private SelectionAdapter cancelListener;
75 private Composite pageContainer;
76 private final PageContainerFillLayout pageContainerLayout = new PageContainerFillLayout(
77 5, 5, 300, 225);
78 private int pageWidth = SWT.DEFAULT;
79 private int pageHeight = SWT.DEFAULT;
80 private ListenerList pageChangedListeners = new ListenerList(ListenerList.IDENTITY);
81 /***
82 * A layout for a container which includes several pages, like a notebook,
83 * wizard, or preference dialog. The size computed by this layout is the
84 * maximum width and height of all pages currently inserted into the
85 * container.
86 */
87 protected class PageContainerFillLayout extends Layout {
88 /***
89 * The margin width; <code>5</code> pixels by default.
90 */
91 public int marginWidth = 5;
92 /***
93 * The margin height; <code>5</code> pixels by default.
94 */
95 public int marginHeight = 5;
96 /***
97 * The minimum width; <code>0</code> pixels by default.
98 */
99 public int minimumWidth = 0;
100 /***
101 * The minimum height; <code>0</code> pixels by default.
102 */
103 public int minimumHeight = 0;
104 /***
105 * Creates new layout object.
106 * @param mw the margin width
107 * @param mh the margin height
108 * @param minW the minimum width
109 * @param minH the minimum height
110 */
111 public PageContainerFillLayout(int mw, int mh, int minW, int minH) {
112 marginWidth = mw;
113 marginHeight = mh;
114 minimumWidth = minW;
115 minimumHeight = minH;
116 }
117
118
119
120 @Override
121 public Point computeSize(Composite composite, int wHint, int hHint,
122 boolean force) {
123 if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT)
124 return new Point(wHint, hHint);
125 Point result = null;
126 Control[] children = composite.getChildren();
127 if (children.length > 0) {
128 result = new Point(0, 0);
129 for (int i = 0; i < children.length; i++) {
130 Point cp = children[i].computeSize(wHint, hHint, force);
131 result.x = Math.max(result.x, cp.x);
132 result.y = Math.max(result.y, cp.y);
133 }
134 result.x = result.x + 2 * marginWidth;
135 result.y = result.y + 2 * marginHeight;
136 } else {
137 Rectangle rect = composite.getClientArea();
138 result = new Point(rect.width, rect.height);
139 }
140 result.x = Math.max(result.x, minimumWidth);
141 result.y = Math.max(result.y, minimumHeight);
142 if (wHint != SWT.DEFAULT)
143 result.x = wHint;
144 if (hHint != SWT.DEFAULT)
145 result.y = hHint;
146 return result;
147 }
148 /***
149 * Returns the client area for the given composite according to this
150 * layout.
151 * @param c the composite
152 * @return the client area rectangle
153 */
154 public Rectangle getClientArea(Composite c) {
155 Rectangle rect = c.getClientArea();
156 rect.x = rect.x + marginWidth;
157 rect.y = rect.y + marginHeight;
158 rect.width = rect.width - 2 * marginWidth;
159 rect.height = rect.height - 2 * marginHeight;
160 return rect;
161 }
162
163
164
165 @Override
166 public void layout(Composite composite, boolean force) {
167 Rectangle rect = getClientArea(composite);
168 Control[] children = composite.getChildren();
169 for (int i = 0; i < children.length; i++) {
170 children[i].setBounds(rect);
171 }
172 }
173 /***
174 * Lays outs the page according to this layout.
175 * @param w the control
176 */
177 public void layoutPage(Control w) {
178 w.setBounds(getClientArea(w.getParent()));
179 }
180 /***
181 * Sets the location of the page so that its origin is in the upper left
182 * corner.
183 * @param w the control
184 */
185 public void setPageLocation(Control w) {
186 w.setLocation(marginWidth, marginHeight);
187 }
188 }
189 /***
190 * The name of the functionality that the wizard provides. Shown in the
191 * window caption.
192 */
193 private final String processName;
194 /***
195 * Creates a new wizard dialog for the given wizard.
196 * @param parentShell the parent shell
197 * @param newWizard the wizard this dialog is working on
198 * @param processName the name of the functionality that the wizard
199 * provides. Shown in the window caption.
200 */
201 public WizardDialog(Shell parentShell, IWizard newWizard, String processName) {
202 super(parentShell);
203 if (newWizard == null)
204 throw new IllegalArgumentException("wizard must not be null");
205 setShellStyle(SWT.CLOSE | SWT.TITLE | SWT.BORDER
206 | SWT.APPLICATION_MODAL | SWT.RESIZE | getDefaultOrientation());
207 wizard = newWizard;
208 this.processName = processName;
209
210
211 cancelListener = new SelectionAdapter() {
212
213
214
215
216 @Override
217 public void widgetSelected(SelectionEvent e) {
218 cancelPressed();
219 }
220 };
221 }
222
223
224
225
226 @Override
227 protected void configureShell(Shell newShell) {
228 super.configureShell(newShell);
229 newShell.setText(processName);
230 }
231 /***
232 * On these composites the page controls are placed. Last composite shows
233 * the current page.
234 */
235 private final List<Composite> pageTiles = new ArrayList<Composite>();
236 /***
237 * List of wizard pages. Last page is the page currently being shown.
238 */
239 private final List<BaseWizardPage> wizardPages = new ArrayList<BaseWizardPage>();
240 /***
241 * The Back button has been pressed.
242 */
243 protected void backPressed() {
244 if (!wizard.hasPrevious())
245 throw new IllegalStateException("The button must be grayed out");
246 BaseWizardPage current = wizard.current();
247
248 current.dispose();
249 final Composite lastTile = pageTiles.get(pageTiles.size() - 1);
250 BaseWizardPage lastPage = wizardPages.get(wizardPages.size() - 1);
251 if (lastPage != current)
252 throw new IllegalStateException("The wizard offers illegal pages.");
253 lastTile.dispose();
254 pageTiles.remove(pageTiles.size() - 1);
255 wizardPages.remove(wizardPages.size() - 1);
256 current = wizard.previous();
257 lastPage = wizardPages.get(wizardPages.size() - 1);
258 if (lastPage != current)
259 throw new IllegalStateException("The wizard offers illegal pages.");
260 showLastPage();
261 firePageChanged();
262 }
263
264
265
266 @Override
267 protected void buttonPressed(int buttonId) {
268 switch (buttonId) {
269 case IDialogConstants.BACK_ID: {
270 backPressed();
271 break;
272 }
273 case IDialogConstants.NEXT_ID: {
274 nextPressed();
275 break;
276 }
277 case IDialogConstants.FINISH_ID: {
278 finishPressed();
279 break;
280 }
281
282 }
283 }
284 /***
285 * Calculates the difference in size between the given page and the page
286 * container. A larger page results in a positive delta.
287 * @param tile composite where the page is placed.
288 * @return the size difference encoded as a
289 * <code>new Point(deltaWidth,deltaHeight)</code>
290 */
291 private Point calculatePageSizeDelta(Composite tile) {
292 Point contentSize = tile.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
293 Rectangle rect = pageContainerLayout.getClientArea(pageContainer);
294 Point containerSize = new Point(rect.width, rect.height);
295 return new Point(Math.max(0, contentSize.x - containerSize.x), Math
296 .max(0, contentSize.y - containerSize.y));
297 }
298
299
300
301 @Override
302 protected void cancelPressed() {
303
304
305
306
307 setReturnCode(CANCEL);
308 close();
309 }
310
311
312
313
314 @Override
315 public boolean close() {
316 if (okToClose())
317 return hardClose();
318 return false;
319 }
320 /***
321 * Creates and returns the contents of this dialog's button bar.
322 * <p>
323 * The <code>WizardDialog</code> implementation of this framework method
324 * prevents the composite's columns from being made equal width in order to
325 * remove the margin between the Back and Next buttons.
326 * </p>
327 * @param parent the parent composite to contain the button bar
328 * @return the button bar control
329 */
330 @Override
331 protected Control createButtonBar(Composite parent) {
332 Composite composite = (Composite) super.createButtonBar(parent);
333 ((GridLayout) composite.getLayout()).makeColumnsEqualWidth = false;
334 return composite;
335 }
336
337
338
339 @Override
340 protected void createButtonsForButtonBar(Composite parent) {
341 createPreviousAndNextButtons(parent);
342 finishButton = createButton(parent, IDialogConstants.FINISH_ID,
343 IDialogConstants.FINISH_LABEL, true);
344 cancelButton = createCancelButton(parent);
345 }
346 /***
347 * Creates the Cancel button for this wizard dialog. Creates a standard (<code>SWT.PUSH</code>)
348 * button and registers for its selection events. Note that the number of
349 * columns in the button bar composite is incremented. The Cancel button is
350 * created specially to give it a removeable listener.
351 * @param parent the parent button bar
352 * @return the new Cancel button
353 */
354 private Button createCancelButton(Composite parent) {
355
356 ((GridLayout) parent.getLayout()).numColumns++;
357 Button button = new Button(parent, SWT.PUSH);
358 button.setText(IDialogConstants.CANCEL_LABEL);
359 setButtonLayoutData(button);
360 button.setFont(parent.getFont());
361 button.setData(new Integer(IDialogConstants.CANCEL_ID));
362 button.addSelectionListener(cancelListener);
363 return button;
364 }
365 /***
366 * Return the cancel button if the id is a the cancel id.
367 * @param id the button id
368 * @return the button corresponding to the button id
369 */
370 @Override
371 protected Button getButton(int id) {
372 if (id == IDialogConstants.CANCEL_ID)
373 return cancelButton;
374 return super.getButton(id);
375 }
376 /***
377 * The <code>WizardDialog</code> implementation of this
378 * <code>Window</code> method calls <code>super.createContents</code> to
379 * create the controls. Then it shows the first page.
380 */
381 @Override
382 protected Control createContents(Composite parent) {
383 Control contents = super.createContents(parent);
384
385 final BaseWizardPage first = wizard.current();
386 if (first == null)
387 return contents;
388
389 final Composite tile = new Composite(pageContainer, SWT.NONE);
390 tile.setLayout(new GridLayout(1, false));
391 tile.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
392 first.createControl(tile);
393 first.setContext(pageContext);
394 pageTiles.add(tile);
395 wizardPages.add(first);
396
397 showLastPage();
398 return contents;
399 }
400
401
402
403 @Override
404 protected Control createDialogArea(Composite parent) {
405 Composite composite = (Composite) super.createDialogArea(parent);
406
407 pageContainer = createPageContainer(composite);
408 GridData gd = new GridData(GridData.FILL_BOTH);
409 gd.widthHint = pageWidth;
410 gd.heightHint = pageHeight;
411 pageContainer.setLayoutData(gd);
412 pageContainer.setFont(parent.getFont());
413
414 GridLayout pmlayout = new GridLayout();
415 pmlayout.numColumns = 1;
416
417 Label separator = new Label(composite, SWT.HORIZONTAL | SWT.SEPARATOR);
418 separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
419 return composite;
420 }
421 /***
422 * Creates the container that holds all pages.
423 * @param parent
424 * @return Composite
425 */
426 private Composite createPageContainer(Composite parent) {
427 Composite result = new Composite(parent, SWT.NULL);
428 result.setLayout(pageContainerLayout);
429 return result;
430 }
431 /***
432 * Creates the Previous and Next buttons for this wizard dialog. Creates
433 * standard (<code>SWT.PUSH</code>) buttons and registers for their
434 * selection events. Note that the number of columns in the button bar
435 * composite is incremented. These buttons are created specially to prevent
436 * any space between them.
437 * @param parent the parent button bar
438 * @return a composite containing the new buttons
439 */
440 private Composite createPreviousAndNextButtons(Composite parent) {
441
442 ((GridLayout) parent.getLayout()).numColumns++;
443 Composite composite = new Composite(parent, SWT.NONE);
444
445
446 GridLayout layout = new GridLayout();
447 layout.numColumns = 0;
448 layout.marginWidth = 0;
449 layout.marginHeight = 0;
450 layout.horizontalSpacing = 0;
451 layout.verticalSpacing = 0;
452 composite.setLayout(layout);
453 GridData data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER
454 | GridData.VERTICAL_ALIGN_CENTER);
455 composite.setLayoutData(data);
456 composite.setFont(parent.getFont());
457 backButton = createButton(composite, IDialogConstants.BACK_ID,
458 IDialogConstants.BACK_LABEL, false);
459 nextButton = createButton(composite, IDialogConstants.NEXT_ID,
460 IDialogConstants.NEXT_LABEL, false);
461 return composite;
462 }
463 /***
464 * The Finish button has been pressed.
465 */
466 protected void finishPressed() {
467 if (!wizard.canFinish())
468 throw new IllegalStateException("Finish button should be disabled");
469
470
471
472
473
474
475
476
477 if (wizard.performFinish()) {
478
479 setReturnCode(OK);
480 hardClose();
481 }
482 }
483 /***
484 * Returns page, currently shown on screen.
485 * @return currently shown page.
486 */
487 public BaseWizardPage getCurrentPage() {
488 return wizard.current();
489 }
490 /***
491 * Returns the wizard this dialog is currently displaying.
492 * @return the current wizard
493 */
494 protected IWizard getWizard() {
495 return wizard;
496 }
497 /***
498 * Closes this window.
499 * @return <code>true</code> if the window is (or was already) closed, and
500 * <code>false</code> if it is still open
501 */
502 private boolean hardClose() {
503
504 for (BaseWizardPage page : wizardPages) {
505 page.dispose();
506 }
507
508 wizard.dispose();
509
510 return super.close();
511 }
512 /***
513 * The Next button has been pressed.
514 */
515 protected void nextPressed() {
516 if (!wizard.hasNext())
517 throw new IllegalStateException("Next button must not be enabled");
518 final BaseWizardPage next;
519 try {
520 next = wizard.next();
521 } catch (ProviderException ex) {
522
523
524 EuroMath.log(IStatus.ERROR, 0,
525 "Provider has thrown error while creating next wizard", ex);
526 MessageDialog.openError(getShell(), Messages.getString("ERROR"), ex
527 .getLocalizedMessage());
528 return;
529 }
530
531 final Composite tile = new Composite(pageContainer, SWT.NONE);
532 tile.setLayout(new GridLayout(1, false));
533 tile.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
534 next.createControl(tile);
535 next.setContext(pageContext);
536 pageTiles.add(tile);
537 wizardPages.add(next);
538
539 showLastPage();
540 firePageChanged();
541 }
542 /***
543 * Checks whether it is alright to close this wizard dialog and performed
544 * standard cancel processing. If there is a long running operation in
545 * progress, this method posts an alert message saying that the wizard
546 * cannot be closed.
547 * @return <code>true</code> if it is alright to close this dialog, and
548 * <code>false</code> if it is not
549 */
550 private boolean okToClose() {
551 return wizard.performCancel();
552 }
553 /***
554 * Sets the minimum page size used for the pages.
555 * @param minWidth the minimum page width
556 * @param minHeight the minimum page height
557 * @see #setMinimumPageSize(Point)
558 */
559 public void setMinimumPageSize(int minWidth, int minHeight) {
560 Assert.isTrue(minWidth >= 0 && minHeight >= 0);
561 pageContainerLayout.minimumWidth = minWidth;
562 pageContainerLayout.minimumHeight = minHeight;
563 }
564 /***
565 * Sets the minimum page size used for the pages.
566 * @param size the page size encoded as <code>new Point(width,height)</code>
567 * @see #setMinimumPageSize(int,int)
568 */
569 public void setMinimumPageSize(Point size) {
570 setMinimumPageSize(size.x, size.y);
571 }
572 /***
573 * Sets the size of all pages. The given size takes precedence over computed
574 * sizes.
575 * @param width the page width
576 * @param height the page height
577 * @see #setPageSize(Point)
578 */
579 public void setPageSize(int width, int height) {
580 pageWidth = width;
581 pageHeight = height;
582 }
583 /***
584 * Sets the size of all pages. The given size takes precedence over computed
585 * sizes.
586 * @param size the page size encoded as <code>new Point(width,height)</code>
587 * @see #setPageSize(int,int)
588 */
589 public void setPageSize(Point size) {
590 setPageSize(size.x, size.y);
591 }
592 /***
593 * Ensures that the last page is the visible one.
594 */
595 private void showLastPage() {
596 final Composite currentTile = pageTiles.get(pageTiles.size() - 1);
597 currentTile.setVisible(true);
598 if (pageTiles.size() > 1) {
599 final Composite prevTile = pageTiles.get(pageTiles.size() - 2);
600 prevTile.setVisible(false);
601 }
602
603 updateSize(currentTile);
604
605 update();
606 }
607 /***
608 * Updates this dialog's controls to reflect the current page.
609 */
610 protected void update() {
611
612 updateTitleBar();
613
614 updateButtons();
615 }
616 /***
617 * Updates buttons state.
618 */
619 private void updateButtons() {
620 final boolean canFinish = wizard.canFinish();
621 final boolean canFlipToNextPage = wizard.hasNext();
622 backButton.setEnabled(wizard.hasPrevious());
623 nextButton.setEnabled(canFlipToNextPage);
624 finishButton.setEnabled(canFinish);
625
626 if (canFlipToNextPage && !canFinish)
627 getShell().setDefaultButton(nextButton);
628 else
629 getShell().setDefaultButton(finishButton);
630 }
631
632
633
634
635
636 @Override
637 public void setMessage(String newMessage, int newType) {
638 super.setMessage(newMessage, newType);
639 currentMessage = newMessage;
640 currentMessageLevel = newType;
641 }
642
643
644
645
646 @Override
647 public void setErrorMessage(String newErrorMessage) {
648 super.setErrorMessage(newErrorMessage);
649 currentErrorMessage = newErrorMessage;
650 }
651 /***
652 * Returns current error message.
653 * @return current error message.
654 */
655 public String getErrorMessage() {
656 return currentErrorMessage;
657 }
658 /***
659 * Returns current message.
660 * @return current message.
661 */
662 public String getMessage() {
663 return currentMessage;
664 }
665 /***
666 * Returns current message's level.
667 * @return current message's level.
668 */
669 public int getMessageType() {
670 return currentMessageLevel;
671 }
672 /***
673 * Updates currently shown messages from current page.
674 */
675 private void updateMessage() {
676 if (wizard.current() == null)
677 setMessages(null);
678 else
679 setMessages(wizard.current().getMessages());
680 }
681 /***
682 * Currently shown error message.
683 */
684 private String currentErrorMessage = null;
685 /***
686 * Currently shown message.
687 */
688 private String currentMessage = null;
689 /***
690 * Level of currently shown message.
691 */
692 private int currentMessageLevel = IMessageProvider.NONE;
693 /***
694 * Updates messages.
695 * @param messages validity messages. If <code>null</code> then all
696 * messages are cleared.
697 */
698 private void setMessages(ValidityMessages messages) {
699 if (messages == null) {
700 if (getErrorMessage() != null)
701 setErrorMessage(null);
702 if (getMessage() != null) {
703 setMessage(null, IMessageProvider.NONE);
704 }
705 return;
706 }
707
708 if (!JavaTools.equals(getErrorMessage(), messages.error))
709 setErrorMessage(messages.error);
710 if (messages.error != null) {
711
712 return;
713 }
714
715 if ((getMessageType() != IMessageProvider.WARNING)
716 || (!JavaTools.equals(getMessage(), messages.warning))) {
717
718
719
720 if ((messages.warning != null) || (messages.info == null))
721 setMessage(messages.warning, IMessageProvider.WARNING);
722 }
723 if (messages.warning != null) {
724
725 return;
726 }
727
728 if ((getMessageType() != IMessageProvider.INFORMATION)
729 || (!JavaTools.equals(getMessage(), messages.info))) {
730 setMessage(messages.info, IMessageProvider.INFORMATION);
731 }
732 }
733 /***
734 * Changes the shell size to the given size, ensuring that it is no larger
735 * than the display bounds.
736 * @param width the shell width
737 * @param height the shell height
738 */
739 private void setShellSize(int width, int height) {
740 Rectangle size = getShell().getBounds();
741 size.height = height;
742 size.width = width;
743 getShell().setBounds(getConstrainedShellBounds(size));
744 }
745 /***
746 * Computes the correct dialog size for the current page and resizes its
747 * shell if nessessary. Also causes the container to refresh its layout.
748 * @param tile the composite where the wizard page is placed, to use to
749 * resize the dialog
750 * @since 2.0
751 */
752 protected void updateSize(Composite tile) {
753 updateSizeForPage(tile);
754 pageContainerLayout.layoutPage(tile);
755 }
756 /***
757 * Updates size of the window.
758 */
759 public void updateSize() {
760 updateSize(pageTiles.get(pageTiles.size() - 1));
761 }
762 /***
763 * Computes the correct dialog size for the given page and resizes its shell
764 * if nessessary.
765 * @param tile the composite where the wizard page is placed
766 */
767 private void updateSizeForPage(Composite tile) {
768
769 Point delta = calculatePageSizeDelta(tile);
770 if (delta.x > 0 || delta.y > 0) {
771
772 Shell shell = getShell();
773 Point shellSize = shell.getSize();
774 setShellSize(shellSize.x + delta.x, shellSize.y + delta.y);
775 constrainShellSize();
776 }
777 }
778 /***
779 * Updates the titlebar.
780 */
781 private void updateTitleBar() {
782 final String s = StringTools.nonNullStr(wizard.getName());
783 setTitle(s);
784 final BaseWizardPage currentPage = wizard.current();
785 if (currentPage != null)
786 setTitleImage(currentPage.titleImage);
787 updateMessage();
788 }
789
790
791
792
793 public Object getSelectedPage() {
794 return getCurrentPage();
795 }
796
797
798
799
800 public void addPageChangedListener(IPageChangedListener listener) {
801 pageChangedListeners.add(listener);
802 }
803
804
805
806
807 public void removePageChangedListener(IPageChangedListener listener) {
808 pageChangedListeners.remove(listener);
809 }
810 /***
811 * Notifies any selection changed listeners that the selected page has
812 * changed. Only listeners registered at the time this method is called are
813 * notified.
814 * @see IPageChangedListener#pageChanged
815 */
816 protected void firePageChanged() {
817 final PageChangedEvent event = new PageChangedEvent(this, wizard
818 .current());
819 Object[] listeners = pageChangedListeners.getListeners();
820 for (int i = 0; i < listeners.length; ++i) {
821 final IPageChangedListener l = (IPageChangedListener) listeners[i];
822 SafeRunnable.run(new SafeRunnable() {
823 public void run() {
824 l.pageChanged(event);
825 }
826 });
827 }
828 }
829 /***
830 * The context given to each page.
831 * @author Martin Vysny
832 */
833 private final class PageContext implements IWizardPageContext {
834
835
836
837
838 public Shell getShell() {
839 return WizardDialog.this.getShell();
840 }
841
842
843
844
845 public void updateMessages() {
846 update();
847 }
848 }
849 /***
850 * Context given to each page.
851 */
852 private final IWizardPageContext pageContext = new PageContext();
853 }