0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: * Teddy Walker <teddy.walker@googlemail.com>
0011: * - Bug 188056 [Preferences] PreferencePages have to less indent in PreferenceDialog
0012: *******************************************************************************/package org.eclipse.jface.preference;
0013:
0014: import java.io.IOException;
0015: import java.util.Iterator;
0016: import java.util.List;
0017:
0018: import org.eclipse.core.runtime.Assert;
0019: import org.eclipse.core.runtime.ISafeRunnable;
0020: import org.eclipse.core.runtime.IStatus;
0021: import org.eclipse.core.runtime.ListenerList;
0022: import org.eclipse.core.runtime.SafeRunner;
0023: import org.eclipse.core.runtime.Status;
0024: import org.eclipse.jface.dialogs.DialogMessageArea;
0025: import org.eclipse.jface.dialogs.IDialogConstants;
0026: import org.eclipse.jface.dialogs.IMessageProvider;
0027: import org.eclipse.jface.dialogs.IPageChangeProvider;
0028: import org.eclipse.jface.dialogs.IPageChangedListener;
0029: import org.eclipse.jface.dialogs.MessageDialog;
0030: import org.eclipse.jface.dialogs.PageChangedEvent;
0031: import org.eclipse.jface.dialogs.TrayDialog;
0032: import org.eclipse.jface.resource.JFaceResources;
0033: import org.eclipse.jface.util.IPropertyChangeListener;
0034: import org.eclipse.jface.util.Policy;
0035: import org.eclipse.jface.util.PropertyChangeEvent;
0036: import org.eclipse.jface.util.SafeRunnable;
0037: import org.eclipse.jface.viewers.ISelection;
0038: import org.eclipse.jface.viewers.ISelectionChangedListener;
0039: import org.eclipse.jface.viewers.IStructuredSelection;
0040: import org.eclipse.jface.viewers.SelectionChangedEvent;
0041: import org.eclipse.jface.viewers.StructuredSelection;
0042: import org.eclipse.jface.viewers.TreeViewer;
0043: import org.eclipse.jface.viewers.ViewerFilter;
0044: import org.eclipse.swt.SWT;
0045: import org.eclipse.swt.custom.BusyIndicator;
0046: import org.eclipse.swt.custom.ScrolledComposite;
0047: import org.eclipse.swt.events.ControlAdapter;
0048: import org.eclipse.swt.events.ControlEvent;
0049: import org.eclipse.swt.events.DisposeEvent;
0050: import org.eclipse.swt.events.DisposeListener;
0051: import org.eclipse.swt.events.HelpEvent;
0052: import org.eclipse.swt.events.HelpListener;
0053: import org.eclipse.swt.events.SelectionAdapter;
0054: import org.eclipse.swt.events.SelectionEvent;
0055: import org.eclipse.swt.events.ShellAdapter;
0056: import org.eclipse.swt.events.ShellEvent;
0057: import org.eclipse.swt.graphics.Font;
0058: import org.eclipse.swt.graphics.Point;
0059: import org.eclipse.swt.graphics.Rectangle;
0060: import org.eclipse.swt.layout.FormAttachment;
0061: import org.eclipse.swt.layout.FormData;
0062: import org.eclipse.swt.layout.FormLayout;
0063: import org.eclipse.swt.layout.GridData;
0064: import org.eclipse.swt.layout.GridLayout;
0065: import org.eclipse.swt.widgets.Button;
0066: import org.eclipse.swt.widgets.Composite;
0067: import org.eclipse.swt.widgets.Control;
0068: import org.eclipse.swt.widgets.Event;
0069: import org.eclipse.swt.widgets.Label;
0070: import org.eclipse.swt.widgets.Layout;
0071: import org.eclipse.swt.widgets.Listener;
0072: import org.eclipse.swt.widgets.Sash;
0073: import org.eclipse.swt.widgets.Shell;
0074: import org.eclipse.swt.widgets.Tree;
0075:
0076: /**
0077: * A preference dialog is a hierarchical presentation of preference pages. Each
0078: * page is represented by a node in the tree shown on the left hand side of the
0079: * dialog; when a node is selected, the corresponding page is shown on the right
0080: * hand side.
0081: */
0082: public class PreferenceDialog extends TrayDialog implements
0083: IPreferencePageContainer, IPageChangeProvider {
0084: /**
0085: * Layout for the page container.
0086: *
0087: */
0088: private class PageLayout extends Layout {
0089: public Point computeSize(Composite composite, int wHint,
0090: int hHint, boolean force) {
0091: if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) {
0092: return new Point(wHint, hHint);
0093: }
0094: int x = minimumPageSize.x;
0095: int y = minimumPageSize.y;
0096: Control[] children = composite.getChildren();
0097: for (int i = 0; i < children.length; i++) {
0098: Point size = children[i].computeSize(SWT.DEFAULT,
0099: SWT.DEFAULT, force);
0100: x = Math.max(x, size.x);
0101: y = Math.max(y, size.y);
0102: }
0103:
0104: //As pages can implement thier own computeSize
0105: //take it into account
0106: if (currentPage != null) {
0107: Point size = currentPage.computeSize();
0108: x = Math.max(x, size.x);
0109: y = Math.max(y, size.y);
0110: }
0111:
0112: if (wHint != SWT.DEFAULT) {
0113: x = wHint;
0114: }
0115: if (hHint != SWT.DEFAULT) {
0116: y = hHint;
0117: }
0118: return new Point(x, y);
0119: }
0120:
0121: public void layout(Composite composite, boolean force) {
0122: Rectangle rect = composite.getClientArea();
0123: Control[] children = composite.getChildren();
0124: for (int i = 0; i < children.length; i++) {
0125: children[i].setSize(rect.width, rect.height);
0126: }
0127: }
0128: }
0129:
0130: //The id of the last page that was selected
0131: private static String lastPreferenceId = null;
0132:
0133: //The last known tree width
0134: private static int lastTreeWidth = 180;
0135:
0136: /**
0137: * Indentifier for the error image
0138: */
0139: public static final String PREF_DLG_IMG_TITLE_ERROR = DLG_IMG_MESSAGE_ERROR;
0140:
0141: /**
0142: * Title area fields
0143: */
0144: public static final String PREF_DLG_TITLE_IMG = "preference_dialog_title_image"; //$NON-NLS-1$
0145:
0146: /**
0147: * Return code used when dialog failed
0148: */
0149: protected static final int FAILED = 2;
0150:
0151: /**
0152: * The current preference page, or <code>null</code> if there is none.
0153: */
0154: private IPreferencePage currentPage;
0155:
0156: private DialogMessageArea messageArea;
0157:
0158: private Point lastShellSize;
0159:
0160: private IPreferenceNode lastSuccessfulNode;
0161:
0162: /**
0163: * The minimum page size; 400 by 400 by default.
0164: *
0165: * @see #setMinimumPageSize(Point)
0166: */
0167: private Point minimumPageSize = new Point(400, 400);
0168:
0169: /**
0170: * The OK button.
0171: */
0172: private Button okButton;
0173:
0174: /**
0175: * The Composite in which a page is shown.
0176: */
0177: private Composite pageContainer;
0178:
0179: /**
0180: * The preference manager.
0181: */
0182: private PreferenceManager preferenceManager;
0183:
0184: /**
0185: * Flag for the presence of the error message.
0186: */
0187: private boolean showingError = false;
0188:
0189: /**
0190: * Preference store, initially <code>null</code> meaning none.
0191: *
0192: * @see #setPreferenceStore
0193: */
0194: private IPreferenceStore preferenceStore;
0195:
0196: private Composite titleArea;
0197:
0198: /**
0199: * The tree viewer.
0200: */
0201: private TreeViewer treeViewer;
0202:
0203: private ListenerList pageChangedListeners = new ListenerList();
0204:
0205: /**
0206: * Composite with a FormLayout to contain the title area
0207: */
0208: Composite formTitleComposite;
0209:
0210: private ScrolledComposite scrolled;
0211:
0212: /**
0213: * Creates a new preference dialog under the control of the given preference
0214: * manager.
0215: *
0216: * @param parentShell
0217: * the parent shell
0218: * @param manager
0219: * the preference manager
0220: */
0221: public PreferenceDialog(Shell parentShell, PreferenceManager manager) {
0222: super (parentShell);
0223: preferenceManager = manager;
0224: }
0225:
0226: /*
0227: * (non-Javadoc)
0228: *
0229: * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
0230: */
0231: protected void buttonPressed(int buttonId) {
0232: switch (buttonId) {
0233: case IDialogConstants.OK_ID: {
0234: okPressed();
0235: return;
0236: }
0237: case IDialogConstants.CANCEL_ID: {
0238: cancelPressed();
0239: return;
0240: }
0241: case IDialogConstants.HELP_ID: {
0242: helpPressed();
0243: return;
0244: }
0245: }
0246: }
0247:
0248: /*
0249: * (non-Javadoc)
0250: *
0251: * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()
0252: */
0253: protected void cancelPressed() {
0254: // Inform all pages that we are cancelling
0255: Iterator nodes = preferenceManager.getElements(
0256: PreferenceManager.PRE_ORDER).iterator();
0257: while (nodes.hasNext()) {
0258: final IPreferenceNode node = (IPreferenceNode) nodes.next();
0259: if (getPage(node) != null) {
0260: SafeRunnable.run(new SafeRunnable() {
0261: public void run() {
0262: if (!getPage(node).performCancel()) {
0263: return;
0264: }
0265: }
0266: });
0267: }
0268: }
0269: setReturnCode(CANCEL);
0270: close();
0271: }
0272:
0273: /**
0274: * Clear the last selected node. This is so that we not chache the last
0275: * selection in case of an error.
0276: */
0277: void clearSelectedNode() {
0278: setSelectedNodePreference(null);
0279: }
0280:
0281: /*
0282: * (non-Javadoc)
0283: *
0284: * @see org.eclipse.jface.window.Window#close()
0285: */
0286: public boolean close() {
0287:
0288: //Do this is in a SafeRunnable as it may run client code
0289: SafeRunnable runnable = new SafeRunnable() {
0290: /* (non-Javadoc)
0291: * @see org.eclipse.core.runtime.ISafeRunnable#run()
0292: */
0293: public void run() throws Exception {
0294: List nodes = preferenceManager
0295: .getElements(PreferenceManager.PRE_ORDER);
0296: for (int i = 0; i < nodes.size(); i++) {
0297: IPreferenceNode node = (IPreferenceNode) nodes
0298: .get(i);
0299: node.disposeResources();
0300: }
0301:
0302: }
0303:
0304: /* (non-Javadoc)
0305: * @see org.eclipse.jface.util.SafeRunnable#handleException(java.lang.Throwable)
0306: */
0307: public void handleException(Throwable e) {
0308: super .handleException(e);
0309: clearSelectedNode();//Do not cache a node with problems
0310: }
0311: };
0312:
0313: SafeRunner.run(runnable);
0314:
0315: return super .close();
0316: }
0317:
0318: /*
0319: * (non-Javadoc)
0320: *
0321: * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
0322: */
0323: protected void configureShell(Shell newShell) {
0324: super .configureShell(newShell);
0325: newShell.setText(JFaceResources
0326: .getString("PreferenceDialog.title")); //$NON-NLS-1$
0327: newShell.addShellListener(new ShellAdapter() {
0328: public void shellActivated(ShellEvent e) {
0329: if (lastShellSize == null) {
0330: lastShellSize = getShell().getSize();
0331: }
0332: }
0333:
0334: });
0335:
0336: }
0337:
0338: /*
0339: * (non-Javadoc)
0340: *
0341: * @see org.eclipse.jface.window.Window#constrainShellSize()
0342: */
0343: protected void constrainShellSize() {
0344: super .constrainShellSize();
0345: // record opening shell size
0346: if (lastShellSize == null) {
0347: lastShellSize = getShell().getSize();
0348: }
0349: }
0350:
0351: /*
0352: * (non-Javadoc)
0353: *
0354: * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
0355: */
0356: protected void createButtonsForButtonBar(Composite parent) {
0357: // create OK and Cancel buttons by default
0358: okButton = createButton(parent, IDialogConstants.OK_ID,
0359: IDialogConstants.OK_LABEL, true);
0360: getShell().setDefaultButton(okButton);
0361: createButton(parent, IDialogConstants.CANCEL_ID,
0362: IDialogConstants.CANCEL_LABEL, false);
0363: }
0364:
0365: /*
0366: * (non-Javadoc)
0367: *
0368: * @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
0369: */
0370: protected Control createContents(final Composite parent) {
0371: final Control[] control = new Control[1];
0372: BusyIndicator.showWhile(getShell().getDisplay(),
0373: new Runnable() {
0374: public void run() {
0375: control[0] = PreferenceDialog.super
0376: .createContents(parent);
0377: // Add the first page
0378: selectSavedItem();
0379: }
0380: });
0381:
0382: return control[0];
0383: }
0384:
0385: /*
0386: * (non-Javadoc)
0387: *
0388: * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
0389: */
0390: protected Control createDialogArea(Composite parent) {
0391: final Composite composite = (Composite) super
0392: .createDialogArea(parent);
0393: GridLayout parentLayout = ((GridLayout) composite.getLayout());
0394: parentLayout.numColumns = 4;
0395: parentLayout.marginHeight = 0;
0396: parentLayout.marginWidth = 0;
0397: parentLayout.verticalSpacing = 0;
0398: parentLayout.horizontalSpacing = 0;
0399:
0400: composite.setBackground(parent.getDisplay().getSystemColor(
0401: SWT.COLOR_LIST_BACKGROUND));
0402:
0403: Control treeControl = createTreeAreaContents(composite);
0404: createSash(composite, treeControl);
0405:
0406: Label versep = new Label(composite, SWT.SEPARATOR
0407: | SWT.VERTICAL);
0408: GridData verGd = new GridData(GridData.FILL_VERTICAL
0409: | GridData.GRAB_VERTICAL);
0410:
0411: versep.setLayoutData(verGd);
0412: versep.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false,
0413: true));
0414:
0415: Composite pageAreaComposite = new Composite(composite, SWT.NONE);
0416: pageAreaComposite
0417: .setLayoutData(new GridData(GridData.FILL_BOTH));
0418: GridLayout layout = new GridLayout(1, true);
0419: layout.marginHeight = 0;
0420: layout.marginWidth = 0;
0421: layout.verticalSpacing = 0;
0422: pageAreaComposite.setLayout(layout);
0423:
0424: formTitleComposite = new Composite(pageAreaComposite, SWT.NONE);
0425: FormLayout titleLayout = new FormLayout();
0426: titleLayout.marginWidth = 0;
0427: titleLayout.marginHeight = 0;
0428: formTitleComposite.setLayout(titleLayout);
0429:
0430: GridData titleGridData = new GridData(GridData.FILL_HORIZONTAL);
0431: titleGridData.horizontalIndent = IDialogConstants.HORIZONTAL_MARGIN;
0432: formTitleComposite.setLayoutData(titleGridData);
0433:
0434: // Build the title area and separator line
0435: Composite titleComposite = new Composite(formTitleComposite,
0436: SWT.NONE);
0437: layout = new GridLayout();
0438: layout.marginBottom = 5;
0439: layout.marginHeight = 0;
0440: layout.marginWidth = 0;
0441: layout.horizontalSpacing = 0;
0442: titleComposite.setLayout(layout);
0443:
0444: FormData titleFormData = new FormData();
0445: titleFormData.top = new FormAttachment(0, 0);
0446: titleFormData.left = new FormAttachment(0, 0);
0447: titleFormData.right = new FormAttachment(100, 0);
0448: titleFormData.bottom = new FormAttachment(100, 0);
0449:
0450: titleComposite.setLayoutData(titleFormData);
0451: createTitleArea(titleComposite);
0452:
0453: Label separator = new Label(pageAreaComposite, SWT.HORIZONTAL
0454: | SWT.SEPARATOR);
0455:
0456: separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL
0457: | GridData.GRAB_HORIZONTAL));
0458:
0459: // Build the Page container
0460: pageContainer = createPageContainer(pageAreaComposite);
0461: GridData pageContainerData = new GridData(GridData.FILL_BOTH);
0462: pageContainerData.horizontalIndent = IDialogConstants.HORIZONTAL_MARGIN;
0463: pageContainer.setLayoutData(pageContainerData);
0464: // Build the separator line
0465: Label bottomSeparator = new Label(parent, SWT.HORIZONTAL
0466: | SWT.SEPARATOR);
0467: bottomSeparator.setLayoutData(new GridData(
0468: GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
0469: return composite;
0470: }
0471:
0472: /**
0473: * Create the sash with right control on the right. Note
0474: * that this method assumes GridData for the layout data
0475: * of the rightControl.
0476: * @param composite
0477: * @param rightControl
0478: * @return Sash
0479: *
0480: * @since 3.1
0481: */
0482: protected Sash createSash(final Composite composite,
0483: final Control rightControl) {
0484: final Sash sash = new Sash(composite, SWT.VERTICAL);
0485: sash.setLayoutData(new GridData(GridData.FILL_VERTICAL));
0486: sash.setBackground(composite.getDisplay().getSystemColor(
0487: SWT.COLOR_LIST_BACKGROUND));
0488: // the following listener resizes the tree control based on sash deltas.
0489: // If necessary, it will also grow/shrink the dialog.
0490: sash.addListener(SWT.Selection, new Listener() {
0491: /*
0492: * (non-Javadoc)
0493: *
0494: * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
0495: */
0496: public void handleEvent(Event event) {
0497: if (event.detail == SWT.DRAG) {
0498: return;
0499: }
0500: int shift = event.x - sash.getBounds().x;
0501: GridData data = (GridData) rightControl.getLayoutData();
0502: int newWidthHint = data.widthHint + shift;
0503: if (newWidthHint < 20) {
0504: return;
0505: }
0506: Point computedSize = getShell().computeSize(
0507: SWT.DEFAULT, SWT.DEFAULT);
0508: Point currentSize = getShell().getSize();
0509: // if the dialog wasn't of a custom size we know we can shrink
0510: // it if necessary based on sash movement.
0511: boolean customSize = !computedSize.equals(currentSize);
0512: data.widthHint = newWidthHint;
0513: setLastTreeWidth(newWidthHint);
0514: composite.layout(true);
0515: // recompute based on new widget size
0516: computedSize = getShell().computeSize(SWT.DEFAULT,
0517: SWT.DEFAULT);
0518: // if the dialog was of a custom size then increase it only if
0519: // necessary.
0520: if (customSize) {
0521: computedSize.x = Math.max(computedSize.x,
0522: currentSize.x);
0523: }
0524: computedSize.y = Math
0525: .max(computedSize.y, currentSize.y);
0526: if (computedSize.equals(currentSize)) {
0527: return;
0528: }
0529: setShellSize(computedSize.x, computedSize.y);
0530: lastShellSize = getShell().getSize();
0531: }
0532: });
0533: return sash;
0534: }
0535:
0536: /**
0537: * Creates the inner page container.
0538: *
0539: * @param parent
0540: * @return Composite
0541: */
0542: protected Composite createPageContainer(Composite parent) {
0543:
0544: Composite outer = new Composite(parent, SWT.NONE);
0545:
0546: GridData outerData = new GridData(GridData.FILL_BOTH
0547: | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
0548: outerData.horizontalIndent = IDialogConstants.HORIZONTAL_MARGIN;
0549:
0550: outer.setLayout(new GridLayout());
0551: outer.setLayoutData(outerData);
0552:
0553: //Create an outer composite for spacing
0554: scrolled = new ScrolledComposite(outer, SWT.V_SCROLL
0555: | SWT.H_SCROLL);
0556:
0557: scrolled.setExpandHorizontal(true);
0558: scrolled.setExpandVertical(true);
0559:
0560: GridData scrolledData = new GridData(GridData.FILL_BOTH
0561: | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
0562:
0563: scrolled.setLayoutData(scrolledData);
0564:
0565: Composite result = new Composite(scrolled, SWT.NONE);
0566:
0567: GridData resultData = new GridData(GridData.FILL_BOTH
0568: | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
0569:
0570: result.setLayout(getPageLayout());
0571: result.setLayoutData(resultData);
0572:
0573: scrolled.setContent(result);
0574:
0575: return result;
0576: }
0577:
0578: /**
0579: * Return the layout for the composite that contains
0580: * the pages.
0581: * @return PageLayout
0582: *
0583: * @since 3.1
0584: */
0585: protected Layout getPageLayout() {
0586: return new PageLayout();
0587: }
0588:
0589: /**
0590: * Creates the wizard's title area.
0591: *
0592: * @param parent
0593: * the SWT parent for the title area composite.
0594: * @return the created title area composite.
0595: */
0596: protected Composite createTitleArea(Composite parent) {
0597: // Create the title area which will contain
0598: // a title, message, and image.
0599: int margins = 2;
0600: titleArea = new Composite(parent, SWT.NONE);
0601: FormLayout layout = new FormLayout();
0602: layout.marginHeight = 0;
0603: layout.marginWidth = margins;
0604: titleArea.setLayout(layout);
0605:
0606: GridData layoutData = new GridData(GridData.FILL_HORIZONTAL);
0607: layoutData.verticalAlignment = SWT.TOP;
0608: titleArea.setLayoutData(layoutData);
0609:
0610: // Message label
0611: messageArea = new DialogMessageArea();
0612: messageArea.createContents(titleArea);
0613:
0614: titleArea.addControlListener(new ControlAdapter() {
0615: /* (non-Javadoc)
0616: * @see org.eclipse.swt.events.ControlAdapter#controlResized(org.eclipse.swt.events.ControlEvent)
0617: */
0618: public void controlResized(ControlEvent e) {
0619: updateMessage();
0620: }
0621: });
0622:
0623: final IPropertyChangeListener fontListener = new IPropertyChangeListener() {
0624: public void propertyChange(PropertyChangeEvent event) {
0625: if (JFaceResources.BANNER_FONT.equals(event
0626: .getProperty())) {
0627: updateMessage();
0628: }
0629: if (JFaceResources.DIALOG_FONT.equals(event
0630: .getProperty())) {
0631: updateMessage();
0632: Font dialogFont = JFaceResources.getDialogFont();
0633: updateTreeFont(dialogFont);
0634: Control[] children = ((Composite) buttonBar)
0635: .getChildren();
0636: for (int i = 0; i < children.length; i++) {
0637: children[i].setFont(dialogFont);
0638: }
0639: }
0640: }
0641: };
0642:
0643: titleArea.addDisposeListener(new DisposeListener() {
0644: public void widgetDisposed(DisposeEvent event) {
0645: JFaceResources.getFontRegistry().removeListener(
0646: fontListener);
0647: }
0648: });
0649: JFaceResources.getFontRegistry().addListener(fontListener);
0650: messageArea.setTitleLayoutData(createMessageAreaData());
0651: messageArea.setMessageLayoutData(createMessageAreaData());
0652: return titleArea;
0653: }
0654:
0655: /**
0656: * Create the layout data for the message area.
0657: *
0658: * @return FormData for the message area.
0659: */
0660: private FormData createMessageAreaData() {
0661: FormData messageData = new FormData();
0662: messageData.top = new FormAttachment(0);
0663: messageData.bottom = new FormAttachment(100);
0664: messageData.right = new FormAttachment(100);
0665: messageData.left = new FormAttachment(0);
0666: return messageData;
0667: }
0668:
0669: /**
0670: * @param parent
0671: * the SWT parent for the tree area controls.
0672: * @return the new <code>Control</code>.
0673: * @since 3.0
0674: */
0675: protected Control createTreeAreaContents(Composite parent) {
0676: // Build the tree an put it into the composite.
0677: treeViewer = createTreeViewer(parent);
0678: treeViewer.setInput(getPreferenceManager());
0679: updateTreeFont(JFaceResources.getDialogFont());
0680: layoutTreeAreaControl(treeViewer.getControl());
0681: return treeViewer.getControl();
0682: }
0683:
0684: /**
0685: * Create a new <code>TreeViewer</code>.
0686: *
0687: * @param parent
0688: * the parent <code>Composite</code>.
0689: * @return the <code>TreeViewer</code>.
0690: * @since 3.0
0691: */
0692: protected TreeViewer createTreeViewer(Composite parent) {
0693: final TreeViewer viewer = new TreeViewer(parent, SWT.NONE);
0694: addListeners(viewer);
0695: viewer.setLabelProvider(new PreferenceLabelProvider());
0696: viewer.setContentProvider(new PreferenceContentProvider());
0697: return viewer;
0698: }
0699:
0700: /**
0701: * Add the listeners to the tree viewer.
0702: * @param viewer
0703: *
0704: * @since 3.1
0705: */
0706: protected void addListeners(final TreeViewer viewer) {
0707: viewer
0708: .addPostSelectionChangedListener(new ISelectionChangedListener() {
0709: private void handleError() {
0710: try {
0711: // remove the listener temporarily so that the events caused
0712: // by the error handling dont further cause error handling
0713: // to occur.
0714: viewer
0715: .removePostSelectionChangedListener(this );
0716: showPageFlippingAbortDialog();
0717: selectCurrentPageAgain();
0718: clearSelectedNode();
0719: } finally {
0720: viewer
0721: .addPostSelectionChangedListener(this );
0722: }
0723: }
0724:
0725: public void selectionChanged(
0726: SelectionChangedEvent event) {
0727: Object selection = getSingleSelection(event
0728: .getSelection());
0729: if (selection instanceof IPreferenceNode) {
0730: if (!isCurrentPageValid()) {
0731: handleError();
0732: } else if (!showPage((IPreferenceNode) selection)) {
0733: // Page flipping wasn't successful
0734: handleError();
0735: } else {
0736: // Everything went well
0737: lastSuccessfulNode = (IPreferenceNode) selection;
0738: }
0739: }
0740: }
0741: });
0742: ((Tree) viewer.getControl())
0743: .addSelectionListener(new SelectionAdapter() {
0744: public void widgetDefaultSelected(
0745: final SelectionEvent event) {
0746: ISelection selection = viewer.getSelection();
0747: if (selection.isEmpty()) {
0748: return;
0749: }
0750: IPreferenceNode singleSelection = getSingleSelection(selection);
0751: boolean expanded = viewer
0752: .getExpandedState(singleSelection);
0753: viewer.setExpandedState(singleSelection,
0754: !expanded);
0755: }
0756: });
0757: //Register help listener on the tree to use context sensitive help
0758: viewer.getControl().addHelpListener(new HelpListener() {
0759: public void helpRequested(HelpEvent event) {
0760: // call perform help on the current page
0761: if (currentPage != null) {
0762: currentPage.performHelp();
0763: }
0764: }
0765: });
0766: }
0767:
0768: /**
0769: * Find the <code>IPreferenceNode</code> that has data the same id as the
0770: * supplied value.
0771: *
0772: * @param nodeId
0773: * the id to search for.
0774: * @return <code>IPreferenceNode</code> or <code>null</code> if not
0775: * found.
0776: */
0777: protected IPreferenceNode findNodeMatching(String nodeId) {
0778: List nodes = preferenceManager
0779: .getElements(PreferenceManager.POST_ORDER);
0780: for (Iterator i = nodes.iterator(); i.hasNext();) {
0781: IPreferenceNode node = (IPreferenceNode) i.next();
0782: if (node.getId().equals(nodeId)) {
0783: return node;
0784: }
0785: }
0786: return null;
0787: }
0788:
0789: /**
0790: * Get the last known right side width.
0791: *
0792: * @return the width.
0793: */
0794: protected int getLastRightWidth() {
0795: return lastTreeWidth;
0796: }
0797:
0798: /**
0799: * Returns the preference mananger used by this preference dialog.
0800: *
0801: * @return the preference mananger
0802: */
0803: public PreferenceManager getPreferenceManager() {
0804: return preferenceManager;
0805: }
0806:
0807: /*
0808: * (non-Javadoc)
0809: *
0810: * @see org.eclipse.jface.preference.IPreferencePageContainer#getPreferenceStore()
0811: */
0812: public IPreferenceStore getPreferenceStore() {
0813: return preferenceStore;
0814: }
0815:
0816: /**
0817: * Get the name of the selected item preference
0818: *
0819: * @return String
0820: */
0821: protected String getSelectedNodePreference() {
0822: return lastPreferenceId;
0823: }
0824:
0825: /**
0826: * @param selection
0827: * the <code>ISelection</code> to examine.
0828: * @return the first element, or null if empty.
0829: */
0830: protected IPreferenceNode getSingleSelection(ISelection selection) {
0831: if (!selection.isEmpty()) {
0832: IStructuredSelection structured = (IStructuredSelection) selection;
0833: if (structured.getFirstElement() instanceof IPreferenceNode) {
0834: return (IPreferenceNode) structured.getFirstElement();
0835: }
0836: }
0837: return null;
0838: }
0839:
0840: /**
0841: * @return the <code>TreeViewer</code> for this dialog.
0842: * @since 3.3
0843: */
0844: public TreeViewer getTreeViewer() {
0845: return treeViewer;
0846: }
0847:
0848: /**
0849: * Save the values specified in the pages.
0850: * <p>
0851: * The default implementation of this framework method saves all pages of
0852: * type <code>PreferencePage</code> (if their store needs saving and is a
0853: * <code>PreferenceStore</code>).
0854: * </p>
0855: * <p>
0856: * Subclasses may override.
0857: * </p>
0858: */
0859: protected void handleSave() {
0860: Iterator nodes = preferenceManager.getElements(
0861: PreferenceManager.PRE_ORDER).iterator();
0862: while (nodes.hasNext()) {
0863: IPreferenceNode node = (IPreferenceNode) nodes.next();
0864: IPreferencePage page = node.getPage();
0865: if (page instanceof PreferencePage) {
0866: // Save now in case tbe workbench does not shutdown cleanly
0867: IPreferenceStore store = ((PreferencePage) page)
0868: .getPreferenceStore();
0869: if (store != null && store.needsSaving()
0870: && store instanceof IPersistentPreferenceStore) {
0871: try {
0872: ((IPersistentPreferenceStore) store).save();
0873: } catch (IOException e) {
0874: MessageDialog
0875: .openError(
0876: getShell(),
0877: JFaceResources
0878: .getString("PreferenceDialog.saveErrorTitle"), //$NON-NLS-1$
0879: JFaceResources
0880: .format(
0881: "PreferenceDialog.saveErrorMessage", new Object[] { page.getTitle(), e.getMessage() })); //$NON-NLS-1$
0882: }
0883: }
0884: }
0885: }
0886: }
0887:
0888: /**
0889: * Notifies that the window's close button was pressed, the close menu was
0890: * selected, or the ESCAPE key pressed.
0891: * <p>
0892: * The default implementation of this framework method sets the window's
0893: * return code to <code>CANCEL</code> and closes the window using
0894: * <code>close</code>. Subclasses may extend or reimplement.
0895: * </p>
0896: */
0897: protected void handleShellCloseEvent() {
0898: // handle the same as pressing cancel
0899: cancelPressed();
0900: }
0901:
0902: /**
0903: * Notifies of the pressing of the Help button.
0904: * <p>
0905: * The default implementation of this framework method calls
0906: * <code>performHelp</code> on the currently active page.
0907: * </p>
0908: */
0909: protected void helpPressed() {
0910: if (currentPage != null) {
0911: currentPage.performHelp();
0912: }
0913: }
0914:
0915: /**
0916: * Returns whether the current page is valid.
0917: *
0918: * @return <code>false</code> if the current page is not valid, or or
0919: * <code>true</code> if the current page is valid or there is no
0920: * current page
0921: */
0922: protected boolean isCurrentPageValid() {
0923: if (currentPage == null) {
0924: return true;
0925: }
0926: return currentPage.isValid();
0927: }
0928:
0929: /**
0930: * @param control
0931: * the <code>Control</code> to lay out.
0932: * @since 3.0
0933: */
0934: protected void layoutTreeAreaControl(Control control) {
0935: GridData gd = new GridData(GridData.FILL_VERTICAL);
0936: gd.widthHint = getLastRightWidth();
0937: gd.verticalSpan = 1;
0938: control.setLayoutData(gd);
0939: }
0940:
0941: /**
0942: * The preference dialog implementation of this <code>Dialog</code>
0943: * framework method sends <code>performOk</code> to all pages of the
0944: * preference dialog, then calls <code>handleSave</code> on this dialog to
0945: * save any state, and then calls <code>close</code> to close this dialog.
0946: */
0947: protected void okPressed() {
0948: SafeRunnable.run(new SafeRunnable() {
0949: private boolean errorOccurred;
0950:
0951: /*
0952: * (non-Javadoc)
0953: *
0954: * @see org.eclipse.core.runtime.ISafeRunnable#run()
0955: */
0956: public void run() {
0957: getButton(IDialogConstants.OK_ID).setEnabled(false);
0958: errorOccurred = false;
0959: boolean hasFailedOK = false;
0960: try {
0961: // Notify all the pages and give them a chance to abort
0962: Iterator nodes = preferenceManager.getElements(
0963: PreferenceManager.PRE_ORDER).iterator();
0964: while (nodes.hasNext()) {
0965: IPreferenceNode node = (IPreferenceNode) nodes
0966: .next();
0967: IPreferencePage page = node.getPage();
0968: if (page != null) {
0969: if (!page.performOk()) {
0970: hasFailedOK = true;
0971: return;
0972: }
0973: }
0974: }
0975: } catch (Exception e) {
0976: handleException(e);
0977: } finally {
0978: //Don't bother closing if the OK failed
0979: if (hasFailedOK) {
0980: setReturnCode(FAILED);
0981: getButton(IDialogConstants.OK_ID).setEnabled(
0982: true);
0983: return;
0984: }
0985:
0986: if (!errorOccurred) {
0987: //Give subclasses the choice to save the state of the
0988: //preference pages.
0989: handleSave();
0990: }
0991: setReturnCode(OK);
0992: close();
0993: }
0994: }
0995:
0996: /*
0997: * (non-Javadoc)
0998: *
0999: * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
1000: */
1001: public void handleException(Throwable e) {
1002: errorOccurred = true;
1003:
1004: Policy.getLog().log(
1005: new Status(IStatus.ERROR, Policy.JFACE, 0, e
1006: .toString(), e));
1007:
1008: clearSelectedNode();
1009: String message = JFaceResources
1010: .getString("SafeRunnable.errorMessage"); //$NON-NLS-1$
1011: MessageDialog.openError(getShell(), JFaceResources
1012: .getString("Error"), message); //$NON-NLS-1$
1013:
1014: }
1015: });
1016: }
1017:
1018: /**
1019: * Selects the page determined by <code>lastSuccessfulNode</code> in the
1020: * page hierarchy.
1021: */
1022: void selectCurrentPageAgain() {
1023: if (lastSuccessfulNode == null) {
1024: return;
1025: }
1026: getTreeViewer().setSelection(
1027: new StructuredSelection(lastSuccessfulNode));
1028: currentPage.setVisible(true);
1029: }
1030:
1031: /**
1032: * Selects the saved item in the tree of preference pages. If it cannot do
1033: * this it saves the first one.
1034: */
1035: protected void selectSavedItem() {
1036: IPreferenceNode node = findNodeMatching(getSelectedNodePreference());
1037: if (node == null) {
1038: IPreferenceNode[] nodes = preferenceManager
1039: .getRootSubNodes();
1040: ViewerFilter[] filters = getTreeViewer().getFilters();
1041: for (int i = 0; i < nodes.length; i++) {
1042: IPreferenceNode selectedNode = nodes[i];
1043: // See if it passes all filters
1044: for (int j = 0; j < filters.length; j++) {
1045: if (!filters[j].select(this .treeViewer,
1046: preferenceManager.getRoot(), selectedNode)) {
1047: selectedNode = null;
1048: break;
1049: }
1050: }
1051: // if it passes all filters select it
1052: if (selectedNode != null) {
1053: node = selectedNode;
1054: break;
1055: }
1056: }
1057: }
1058: if (node != null) {
1059: getTreeViewer().setSelection(new StructuredSelection(node),
1060: true);
1061: // Keep focus in tree. See bugs 2692, 2621, and 6775.
1062: getTreeViewer().getControl().setFocus();
1063: }
1064: }
1065:
1066: /**
1067: * Display the given error message. The currently displayed message is saved
1068: * and will be redisplayed when the error message is set to
1069: * <code>null</code>.
1070: *
1071: * @param newErrorMessage
1072: * the errorMessage to display or <code>null</code>
1073: */
1074: public void setErrorMessage(String newErrorMessage) {
1075: if (newErrorMessage == null) {
1076: messageArea.clearErrorMessage();
1077: } else {
1078: messageArea.updateText(newErrorMessage,
1079: IMessageProvider.ERROR);
1080: }
1081: }
1082:
1083: /**
1084: * Save the last known tree width.
1085: *
1086: * @param width
1087: * the width.
1088: */
1089: private void setLastTreeWidth(int width) {
1090: lastTreeWidth = width;
1091: }
1092:
1093: /**
1094: * Set the message text. If the message line currently displays an error,
1095: * the message is stored and will be shown after a call to clearErrorMessage
1096: * <p>
1097: * Shortcut for <code>setMessage(newMessage, NONE)</code>
1098: * </p>
1099: *
1100: * @param newMessage
1101: * the message, or <code>null</code> to clear the message
1102: */
1103: public void setMessage(String newMessage) {
1104: setMessage(newMessage, IMessageProvider.NONE);
1105: }
1106:
1107: /**
1108: * Sets the message for this dialog with an indication of what type of
1109: * message it is.
1110: * <p>
1111: * The valid message types are one of <code>NONE</code>,
1112: * <code>INFORMATION</code>,<code>WARNING</code>, or
1113: * <code>ERROR</code>.
1114: * </p>
1115: * <p>
1116: * Note that for backward compatibility, a message of type
1117: * <code>ERROR</code> is different than an error message (set using
1118: * <code>setErrorMessage</code>). An error message overrides the current
1119: * message until the error message is cleared. This method replaces the
1120: * current message and does not affect the error message.
1121: * </p>
1122: *
1123: * @param newMessage
1124: * the message, or <code>null</code> to clear the message
1125: * @param newType
1126: * the message type
1127: * @since 2.0
1128: */
1129: public void setMessage(String newMessage, int newType) {
1130: messageArea.updateText(newMessage, newType);
1131: }
1132:
1133: /**
1134: * Sets the minimum page size.
1135: *
1136: * @param minWidth
1137: * the minimum page width
1138: * @param minHeight
1139: * the minimum page height
1140: * @see #setMinimumPageSize(Point)
1141: */
1142: public void setMinimumPageSize(int minWidth, int minHeight) {
1143: minimumPageSize.x = minWidth;
1144: minimumPageSize.y = minHeight;
1145: }
1146:
1147: /**
1148: * Sets the minimum page size.
1149: *
1150: * @param size
1151: * the page size encoded as <code>new Point(width,height)</code>
1152: * @see #setMinimumPageSize(int,int)
1153: */
1154: public void setMinimumPageSize(Point size) {
1155: minimumPageSize.x = size.x;
1156: minimumPageSize.y = size.y;
1157: }
1158:
1159: /**
1160: * Sets the preference store for this preference dialog.
1161: *
1162: * @param store
1163: * the preference store
1164: * @see #getPreferenceStore
1165: */
1166: public void setPreferenceStore(IPreferenceStore store) {
1167: Assert.isNotNull(store);
1168: preferenceStore = store;
1169: }
1170:
1171: /**
1172: * Save the currently selected node.
1173: */
1174: private void setSelectedNode() {
1175: String storeValue = null;
1176: IStructuredSelection selection = (IStructuredSelection) getTreeViewer()
1177: .getSelection();
1178: if (selection.size() == 1) {
1179: IPreferenceNode node = (IPreferenceNode) selection
1180: .getFirstElement();
1181: storeValue = node.getId();
1182: }
1183: setSelectedNodePreference(storeValue);
1184: }
1185:
1186: /**
1187: * Sets the name of the selected item preference. Public equivalent to
1188: * <code>setSelectedNodePreference</code>.
1189: *
1190: * @param pageId
1191: * The identifier for the page
1192: * @since 3.0
1193: */
1194: public void setSelectedNode(String pageId) {
1195: setSelectedNodePreference(pageId);
1196: }
1197:
1198: /**
1199: * Sets the name of the selected item preference.
1200: *
1201: * @param pageId
1202: * The identifier for the page
1203: */
1204: protected void setSelectedNodePreference(String pageId) {
1205: lastPreferenceId = pageId;
1206: }
1207:
1208: /**
1209: * Changes the shell size to the given size, ensuring that it is no larger
1210: * than the display bounds.
1211: *
1212: * @param width
1213: * the shell width
1214: * @param height
1215: * the shell height
1216: */
1217: private void setShellSize(int width, int height) {
1218: Rectangle preferred = getShell().getBounds();
1219: preferred.width = width;
1220: preferred.height = height;
1221: getShell().setBounds(getConstrainedShellBounds(preferred));
1222: }
1223:
1224: /**
1225: * Shows the preference page corresponding to the given preference node.
1226: * Does nothing if that page is already current.
1227: *
1228: * @param node
1229: * the preference node, or <code>null</code> if none
1230: * @return <code>true</code> if the page flip was successful, and
1231: * <code>false</code> is unsuccessful
1232: */
1233: protected boolean showPage(IPreferenceNode node) {
1234: if (node == null) {
1235: return false;
1236: }
1237: // Create the page if nessessary
1238: if (node.getPage() == null) {
1239: createPage(node);
1240: }
1241: if (node.getPage() == null) {
1242: return false;
1243: }
1244: IPreferencePage newPage = getPage(node);
1245: if (newPage == currentPage) {
1246: return true;
1247: }
1248: if (currentPage != null) {
1249: if (!currentPage.okToLeave()) {
1250: return false;
1251: }
1252: }
1253: IPreferencePage oldPage = currentPage;
1254: currentPage = newPage;
1255: // Set the new page's container
1256: currentPage.setContainer(this );
1257: // Ensure that the page control has been created
1258: // (this allows lazy page control creation)
1259: if (currentPage.getControl() == null) {
1260: final boolean[] failed = { false };
1261: SafeRunnable.run(new ISafeRunnable() {
1262: public void handleException(Throwable e) {
1263: failed[0] = true;
1264: }
1265:
1266: public void run() {
1267: createPageControl(currentPage, pageContainer);
1268: }
1269: });
1270: if (failed[0]) {
1271: return false;
1272: }
1273: // the page is responsible for ensuring the created control is
1274: // accessable
1275: // via getControl.
1276: Assert.isNotNull(currentPage.getControl());
1277: }
1278: // Force calculation of the page's description label because
1279: // label can be wrapped.
1280: final Point[] size = new Point[1];
1281: final Point failed = new Point(-1, -1);
1282: SafeRunnable.run(new ISafeRunnable() {
1283: public void handleException(Throwable e) {
1284: size[0] = failed;
1285: }
1286:
1287: public void run() {
1288: size[0] = currentPage.computeSize();
1289: }
1290: });
1291: if (size[0].equals(failed)) {
1292: return false;
1293: }
1294: Point contentSize = size[0];
1295: // Do we need resizing. Computation not needed if the
1296: // first page is inserted since computing the dialog's
1297: // size is done by calling dialog.open().
1298: // Also prevent auto resize if the user has manually resized
1299: Shell shell = getShell();
1300: Point shellSize = shell.getSize();
1301: if (oldPage != null) {
1302: Rectangle rect = pageContainer.getClientArea();
1303: Point containerSize = new Point(rect.width, rect.height);
1304: int hdiff = contentSize.x - containerSize.x;
1305: int vdiff = contentSize.y - containerSize.y;
1306: if ((hdiff > 0 || vdiff > 0)
1307: && shellSize.equals(lastShellSize)) {
1308: hdiff = Math.max(0, hdiff);
1309: vdiff = Math.max(0, vdiff);
1310: setShellSize(shellSize.x + hdiff, shellSize.y + vdiff);
1311: lastShellSize = shell.getSize();
1312: if (currentPage.getControl().getSize().x == 0) {
1313: currentPage.getControl().setSize(containerSize);
1314: }
1315:
1316: } else {
1317: currentPage.setSize(containerSize);
1318: }
1319: }
1320:
1321: scrolled.setMinSize(contentSize);
1322: // Ensure that all other pages are invisible
1323: // (including ones that triggered an exception during
1324: // their creation).
1325: Control[] children = pageContainer.getChildren();
1326: Control currentControl = currentPage.getControl();
1327: for (int i = 0; i < children.length; i++) {
1328: if (children[i] != currentControl) {
1329: children[i].setVisible(false);
1330: }
1331: }
1332: // Make the new page visible
1333: currentPage.setVisible(true);
1334: if (oldPage != null) {
1335: oldPage.setVisible(false);
1336: }
1337: // update the dialog controls
1338: update();
1339: return true;
1340: }
1341:
1342: /**
1343: * Create the page for the node.
1344: * @param node
1345: *
1346: * @since 3.1
1347: */
1348: protected void createPage(IPreferenceNode node) {
1349: node.createPage();
1350: }
1351:
1352: /**
1353: * Get the page for the node.
1354: * @param node
1355: * @return IPreferencePage
1356: *
1357: * @since 3.1
1358: */
1359: protected IPreferencePage getPage(IPreferenceNode node) {
1360: return node.getPage();
1361: }
1362:
1363: /**
1364: * Shows the "Page Flipping abort" dialog.
1365: */
1366: void showPageFlippingAbortDialog() {
1367: MessageDialog.openError(getShell(), JFaceResources
1368: .getString("AbortPageFlippingDialog.title"), //$NON-NLS-1$
1369: JFaceResources
1370: .getString("AbortPageFlippingDialog.message")); //$NON-NLS-1$
1371: }
1372:
1373: /**
1374: * Updates this dialog's controls to reflect the current page.
1375: */
1376: protected void update() {
1377: // Update the title bar
1378: updateTitle();
1379: // Update the message line
1380: updateMessage();
1381: // Update the buttons
1382: updateButtons();
1383: //Saved the selected node in the preferences
1384: setSelectedNode();
1385: firePageChanged(new PageChangedEvent(this , getCurrentPage()));
1386: }
1387:
1388: /*
1389: * (non-Javadoc)
1390: *
1391: * @see org.eclipse.jface.preference.IPreferencePageContainer#updateButtons()
1392: */
1393: public void updateButtons() {
1394: okButton.setEnabled(isCurrentPageValid());
1395: }
1396:
1397: /*
1398: * (non-Javadoc)
1399: *
1400: * @see org.eclipse.jface.preference.IPreferencePageContainer#updateMessage()
1401: */
1402: public void updateMessage() {
1403: String message = null;
1404: String errorMessage = null;
1405: if (currentPage != null) {
1406: message = currentPage.getMessage();
1407: errorMessage = currentPage.getErrorMessage();
1408: }
1409: int messageType = IMessageProvider.NONE;
1410: if (message != null && currentPage instanceof IMessageProvider) {
1411: messageType = ((IMessageProvider) currentPage)
1412: .getMessageType();
1413: }
1414:
1415: if (errorMessage == null) {
1416: if (showingError) {
1417: // we were previously showing an error
1418: showingError = false;
1419: }
1420: } else {
1421: message = errorMessage;
1422: messageType = IMessageProvider.ERROR;
1423: if (!showingError) {
1424: // we were not previously showing an error
1425: showingError = true;
1426: }
1427: }
1428: messageArea.updateText(message, messageType);
1429: }
1430:
1431: /*
1432: * (non-Javadoc)
1433: *
1434: * @see org.eclipse.jface.preference.IPreferencePageContainer#updateTitle()
1435: */
1436: public void updateTitle() {
1437: if (currentPage == null) {
1438: return;
1439: }
1440: messageArea.showTitle(currentPage.getTitle(), currentPage
1441: .getImage());
1442: }
1443:
1444: /**
1445: * Update the tree to use the specified <code>Font</code>.
1446: *
1447: * @param dialogFont
1448: * the <code>Font</code> to use.
1449: * @since 3.0
1450: */
1451: protected void updateTreeFont(Font dialogFont) {
1452: getTreeViewer().getControl().setFont(dialogFont);
1453: }
1454:
1455: /**
1456: * Returns the currentPage.
1457: * @return IPreferencePage
1458: * @since 3.1
1459: */
1460: protected IPreferencePage getCurrentPage() {
1461: return currentPage;
1462: }
1463:
1464: /**
1465: * Sets the current page.
1466: * @param currentPage
1467: *
1468: * @since 3.1
1469: */
1470: protected void setCurrentPage(IPreferencePage currentPage) {
1471: this .currentPage = currentPage;
1472: }
1473:
1474: /**
1475: * Set the treeViewer.
1476: * @param treeViewer
1477: *
1478: * @since 3.1
1479: */
1480: protected void setTreeViewer(TreeViewer treeViewer) {
1481: this .treeViewer = treeViewer;
1482: }
1483:
1484: /**
1485: * Get the composite that is showing the page.
1486: *
1487: * @return Composite.
1488: *
1489: * @since 3.1
1490: */
1491: protected Composite getPageContainer() {
1492: return this .pageContainer;
1493: }
1494:
1495: /**
1496: * Set the composite that is showing the page.
1497: * @param pageContainer Composite
1498: *
1499: * @since 3.1
1500: */
1501: protected void setPageContainer(Composite pageContainer) {
1502: this .pageContainer = pageContainer;
1503: }
1504:
1505: /**
1506: * Create the page control for the supplied page.
1507: *
1508: * @param page - the preference page to be shown
1509: * @param parent - the composite to parent the page
1510: *
1511: * @since 3.1
1512: */
1513: protected void createPageControl(IPreferencePage page,
1514: Composite parent) {
1515: page.createControl(parent);
1516: }
1517:
1518: /**
1519: * @see org.eclipse.jface.dialogs.IPageChangeProvider#getSelectedPage()
1520: *
1521: * @since 3.1
1522: */
1523: public Object getSelectedPage() {
1524: return getCurrentPage();
1525: }
1526:
1527: /**
1528: * @see org.eclipse.jface.dialogs.IPageChangeProvider#addPageChangedListener(org.eclipse.jface.dialogs.IPageChangedListener)
1529: * @since 3.1
1530: */
1531: public void addPageChangedListener(IPageChangedListener listener) {
1532: pageChangedListeners.add(listener);
1533: }
1534:
1535: /**
1536: * @see org.eclipse.jface.dialogs.IPageChangeProvider#removePageChangedListener(org.eclipse.jface.dialogs.IPageChangedListener)
1537: * @since 3.1
1538: */
1539: public void removePageChangedListener(IPageChangedListener listener) {
1540: pageChangedListeners.remove(listener);
1541:
1542: }
1543:
1544: /**
1545: * Notifies any selection changed listeners that the selected page
1546: * has changed.
1547: * Only listeners registered at the time this method is called are notified.
1548: *
1549: * @param event a selection changed event
1550: *
1551: * @see IPageChangedListener#pageChanged
1552: *
1553: * @since 3.1
1554: */
1555: protected void firePageChanged(final PageChangedEvent event) {
1556: Object[] listeners = pageChangedListeners.getListeners();
1557: for (int i = 0; i < listeners.length; i++) {
1558: final IPageChangedListener l = (IPageChangedListener) listeners[i];
1559: SafeRunnable.run(new SafeRunnable() {
1560: public void run() {
1561: l.pageChanged(event);
1562: }
1563: });
1564: }
1565: }
1566:
1567: /*
1568: * (non-Javadoc)
1569: * @see org.eclipse.jface.dialogs.Dialog#isResizable()
1570: */
1571: protected boolean isResizable() {
1572: return true;
1573: }
1574:
1575: }
|