Mercurial > projects > dwt-addons
view dwtx/jface/preference/PreferenceDialog.d @ 192:c3583c6ec027
Added missing default cases for switch statements
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 03 Nov 2008 22:52:26 +0100 |
parents | 04b47443bb01 |
children |
line wrap: on
line source
/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Teddy Walker <teddy.walker@googlemail.com> * - Bug 188056 [Preferences] PreferencePages have to less indent in PreferenceDialog * Port to the D programming language: * Frank Benoit <benoit@tionex.de> *******************************************************************************/ module dwtx.jface.preference.PreferenceDialog; import dwtx.jface.preference.IPreferencePageContainer; import dwtx.jface.preference.IPreferencePage; import dwtx.jface.preference.IPreferenceNode; import dwtx.jface.preference.IPreferenceStore; import dwtx.jface.preference.IPersistentPreferenceStore; import dwtx.jface.preference.PreferenceManager; import dwtx.jface.preference.PreferencePage; import dwtx.jface.preference.PreferenceLabelProvider; import dwtx.jface.preference.PreferenceContentProvider; import dwt.DWT; import dwt.custom.BusyIndicator; import dwt.custom.ScrolledComposite; import dwt.events.ControlAdapter; import dwt.events.ControlEvent; import dwt.events.DisposeEvent; import dwt.events.DisposeListener; import dwt.events.HelpEvent; import dwt.events.HelpListener; import dwt.events.SelectionAdapter; import dwt.events.SelectionEvent; import dwt.events.ShellAdapter; import dwt.events.ShellEvent; import dwt.graphics.Font; import dwt.graphics.Point; import dwt.graphics.Rectangle; import dwt.layout.FormAttachment; import dwt.layout.FormData; import dwt.layout.FormLayout; import dwt.layout.GridData; import dwt.layout.GridLayout; import dwt.widgets.Button; import dwt.widgets.Composite; import dwt.widgets.Control; import dwt.widgets.Event; import dwt.widgets.Label; import dwt.widgets.Layout; import dwt.widgets.Listener; import dwt.widgets.Sash; import dwt.widgets.Shell; import dwt.widgets.Tree; import dwtx.core.runtime.Assert; import dwtx.core.runtime.ISafeRunnable; import dwtx.core.runtime.IStatus; import dwtx.core.runtime.ListenerList; import dwtx.core.runtime.SafeRunner; import dwtx.core.runtime.Status; import dwtx.jface.dialogs.DialogMessageArea; import dwtx.jface.dialogs.IDialogConstants; import dwtx.jface.dialogs.IMessageProvider; import dwtx.jface.dialogs.IPageChangeProvider; import dwtx.jface.dialogs.IPageChangedListener; import dwtx.jface.dialogs.MessageDialog; import dwtx.jface.dialogs.PageChangedEvent; import dwtx.jface.dialogs.TrayDialog; import dwtx.jface.resource.JFaceResources; import dwtx.jface.util.IPropertyChangeListener; import dwtx.jface.util.Policy; import dwtx.jface.util.PropertyChangeEvent; import dwtx.jface.util.SafeRunnable; import dwtx.jface.viewers.ISelection; import dwtx.jface.viewers.ISelectionChangedListener; import dwtx.jface.viewers.IStructuredSelection; import dwtx.jface.viewers.SelectionChangedEvent; import dwtx.jface.viewers.StructuredSelection; import dwtx.jface.viewers.TreeViewer; import dwtx.jface.viewers.ViewerComparator; import dwtx.jface.viewers.ViewerFilter; import dwt.dwthelper.utils; import dwt.dwthelper.Runnable; import dwtx.dwtxhelper.Collection; /** * A preference dialog is a hierarchical presentation of preference pages. Each * page is represented by a node in the tree shown on the left hand side of the * dialog; when a node is selected, the corresponding page is shown on the right * hand side. */ public class PreferenceDialog : TrayDialog, IPreferencePageContainer, IPageChangeProvider { /** * Layout for the page container. * */ private class PageLayout : Layout { public override Point computeSize(Composite composite, int wHint, int hHint, bool force) { if (wHint !is DWT.DEFAULT && hHint !is DWT.DEFAULT) { return new Point(wHint, hHint); } int x = minimumPageSize.x; int y = minimumPageSize.y; Control[] children = composite.getChildren(); for (int i = 0; i < children.length; i++) { Point size = children[i].computeSize(DWT.DEFAULT, DWT.DEFAULT, force); x = Math.max(x, size.x); y = Math.max(y, size.y); } //As pages can implement thier own computeSize //take it into account if(currentPage !is null){ Point size = currentPage.computeSize(); x = Math.max(x, size.x); y = Math.max(y, size.y); } if (wHint !is DWT.DEFAULT) { x = wHint; } if (hHint !is DWT.DEFAULT) { y = hHint; } return new Point(x, y); } public override void layout(Composite composite, bool force) { Rectangle rect = composite.getClientArea(); Control[] children = composite.getChildren(); for (int i = 0; i < children.length; i++) { children[i].setSize(rect.width, rect.height); } } } //The id of the last page that was selected private static String lastPreferenceId = null; //The last known tree width private static int lastTreeWidth = 180; /** * Indentifier for the error image */ public static const String PREF_DLG_IMG_TITLE_ERROR = DLG_IMG_MESSAGE_ERROR; /** * Title area fields */ public static const String PREF_DLG_TITLE_IMG = "preference_dialog_title_image"; //$NON-NLS-1$ /** * Return code used when dialog failed */ protected static const int FAILED = 2; /** * The current preference page, or <code>null</code> if there is none. */ private IPreferencePage currentPage; private DialogMessageArea messageArea; private Point lastShellSize; private IPreferenceNode lastSuccessfulNode; /** * The minimum page size; 400 by 400 by default. * * @see #setMinimumPageSize(Point) */ private Point minimumPageSize; /** * The OK button. */ private Button okButton; /** * The Composite in which a page is shown. */ private Composite pageContainer; /** * The preference manager. */ private PreferenceManager preferenceManager; /** * Flag for the presence of the error message. */ private bool showingError = false; /** * Preference store, initially <code>null</code> meaning none. * * @see #setPreferenceStore */ private IPreferenceStore preferenceStore; private Composite titleArea; /** * The tree viewer. */ private TreeViewer treeViewer; private ListenerList pageChangedListeners; /** * Composite with a FormLayout to contain the title area */ Composite formTitleComposite; private ScrolledComposite scrolled; /** * Creates a new preference dialog under the control of the given preference * manager. * * @param parentShell * the parent shell * @param manager * the preference manager */ public this(Shell parentShell, PreferenceManager manager) { minimumPageSize = new Point(400, 400); pageChangedListeners = new ListenerList(); super(parentShell); preferenceManager = manager; } /* * (non-Javadoc) * * @see dwtx.jface.dialogs.Dialog#buttonPressed(int) */ protected override void buttonPressed(int buttonId) { switch (buttonId) { case IDialogConstants.OK_ID: { okPressed(); return; } case IDialogConstants.CANCEL_ID: { cancelPressed(); return; } case IDialogConstants.HELP_ID: { helpPressed(); return; } default: } } /* * (non-Javadoc) * * @see dwtx.jface.dialogs.Dialog#cancelPressed() */ protected override void cancelPressed() { // Inform all pages that we are cancelling Iterator nodes = preferenceManager.getElements(PreferenceManager.PRE_ORDER).iterator(); while (nodes.hasNext()) { IPreferenceNode node = cast(IPreferenceNode) nodes.next(); if (getPage(node) !is null) { // this_: strange workaround for compiler error with dmd 1.028 in run() SafeRunnable.run(dgSafeRunnable((IPreferenceNode node_, PreferenceDialog this_) { if (!this_.getPage(node_).performCancel()) { return; } }, cast(IPreferenceNode)node, this )); } } setReturnCode(CANCEL); close(); } /** * Clear the last selected node. This is so that we not chache the last * selection in case of an error. */ void clearSelectedNode() { setSelectedNodePreference(null); } /* * (non-Javadoc) * * @see dwtx.jface.window.Window#close() */ public override bool close() { //Do this is in a SafeRunnable as it may run client code SafeRunnable runnable = new class SafeRunnable{ /* (non-Javadoc) * @see dwtx.core.runtime.ISafeRunnable#run() */ public void run() { auto nodes = preferenceManager.getElements(PreferenceManager.PRE_ORDER); for (int i = 0; i < nodes.size(); i++) { IPreferenceNode node = cast(IPreferenceNode) nodes.get(i); node.disposeResources(); } } /* (non-Javadoc) * @see dwtx.jface.util.SafeRunnable#handleException(java.lang.Throwable) */ public void handleException(Exception e) { super.handleException(e); clearSelectedNode();//Do not cache a node with problems } }; SafeRunner.run(runnable); return super.close(); } /* * (non-Javadoc) * * @see dwtx.jface.window.Window#configureShell(dwt.widgets.Shell) */ protected override void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText(JFaceResources.getString("PreferenceDialog.title")); //$NON-NLS-1$ newShell.addShellListener(new class ShellAdapter { public void shellActivated(ShellEvent e) { if (lastShellSize is null) { lastShellSize = getShell().getSize(); } } }); } /* * (non-Javadoc) * * @see dwtx.jface.window.Window#constrainShellSize() */ protected override void constrainShellSize() { super.constrainShellSize(); // record opening shell size if (lastShellSize is null) { lastShellSize = getShell().getSize(); } } /* * (non-Javadoc) * * @see dwtx.jface.dialogs.Dialog#createButtonsForButtonBar(dwt.widgets.Composite) */ protected override void createButtonsForButtonBar(Composite parent) { // create OK and Cancel buttons by default okButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); getShell().setDefaultButton(okButton); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); } /* * (non-Javadoc) * * @see dwtx.jface.window.Window#createContents(dwt.widgets.Composite) */ protected override Control createContents(Composite parent) { Control[1] control; BusyIndicator.showWhile(getShell().getDisplay(), new class(parent,control) Runnable { Composite parent_; Control[] control_; this(Composite a,Control[] b){ parent_=a; control_=b; } public void run() { control_[0] = callSuperCreateContents(parent_); // Add the first page selectSavedItem(); } }); return control[0]; } private Control callSuperCreateContents( Composite c ){ return super.createContents( c ); } /* * (non-Javadoc) * * @see dwtx.jface.dialogs.Dialog#createDialogArea(dwt.widgets.Composite) */ protected override Control createDialogArea(Composite parent) { final Composite composite = cast(Composite) super.createDialogArea(parent); GridLayout parentLayout = (cast(GridLayout) composite.getLayout()); parentLayout.numColumns = 4; parentLayout.marginHeight = 0; parentLayout.marginWidth = 0; parentLayout.verticalSpacing = 0; parentLayout.horizontalSpacing = 0; composite.setBackground(parent.getDisplay().getSystemColor(DWT.COLOR_LIST_BACKGROUND)); Control treeControl = createTreeAreaContents(composite); createSash(composite,treeControl); Label versep = new Label(composite, DWT.SEPARATOR | DWT.VERTICAL); GridData verGd = new GridData(GridData.FILL_VERTICAL | GridData.GRAB_VERTICAL); versep.setLayoutData(verGd); versep.setLayoutData(new GridData(DWT.LEFT, DWT.FILL, false, true)); Composite pageAreaComposite = new Composite(composite, DWT.NONE); pageAreaComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); GridLayout layout = new GridLayout(1, true); layout.marginHeight = 0; layout.marginWidth = 0; layout.verticalSpacing = 0; pageAreaComposite.setLayout(layout); formTitleComposite = new Composite(pageAreaComposite, DWT.NONE); FormLayout titleLayout = new FormLayout(); titleLayout.marginWidth = 0; titleLayout.marginHeight = 0; formTitleComposite.setLayout(titleLayout); GridData titleGridData = new GridData(GridData.FILL_HORIZONTAL); titleGridData.horizontalIndent = IDialogConstants.HORIZONTAL_MARGIN; formTitleComposite.setLayoutData(titleGridData); // Build the title area and separator line Composite titleComposite = new Composite(formTitleComposite, DWT.NONE); layout = new GridLayout(); layout.marginBottom = 5; layout.marginHeight = 0; layout.marginWidth = 0; layout.horizontalSpacing = 0; titleComposite.setLayout(layout); FormData titleFormData = new FormData(); titleFormData.top = new FormAttachment(0,0); titleFormData.left = new FormAttachment(0,0); titleFormData.right = new FormAttachment(100,0); titleFormData.bottom = new FormAttachment(100,0); titleComposite.setLayoutData(titleFormData); createTitleArea(titleComposite); Label separator = new Label(pageAreaComposite, DWT.HORIZONTAL | DWT.SEPARATOR); separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL)); // Build the Page container pageContainer = createPageContainer(pageAreaComposite); GridData pageContainerData = new GridData(GridData.FILL_BOTH); pageContainerData.horizontalIndent = IDialogConstants.HORIZONTAL_MARGIN; pageContainer.setLayoutData(pageContainerData); // Build the separator line Label bottomSeparator = new Label(parent, DWT.HORIZONTAL | DWT.SEPARATOR); bottomSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL)); return composite; } /** * Create the sash with right control on the right. Note * that this method assumes GridData for the layout data * of the rightControl. * @param composite * @param rightControl * @return Sash * * @since 3.1 */ protected Sash createSash(Composite composite, Control rightControl) { Sash sash = new Sash(composite, DWT.VERTICAL); sash.setLayoutData(new GridData(GridData.FILL_VERTICAL)); sash.setBackground(composite.getDisplay().getSystemColor(DWT.COLOR_LIST_BACKGROUND)); // the following listener resizes the tree control based on sash deltas. // If necessary, it will also grow/shrink the dialog. sash.addListener(DWT.Selection, new class(composite,rightControl,sash) Listener { Composite composite_; Control rightControl_; Sash sash_; this(Composite a,Control b,Sash c){ composite_=a; rightControl_=b; sash_=c; } /* * (non-Javadoc) * * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event) */ public void handleEvent(Event event) { if (event.detail is DWT.DRAG) { return; } int shift = event.x - sash_.getBounds().x; GridData data = cast(GridData) rightControl_.getLayoutData(); int newWidthHint = data.widthHint + shift; if (newWidthHint < 20) { return; } Point computedSize = getShell().computeSize(DWT.DEFAULT, DWT.DEFAULT); Point currentSize = getShell().getSize(); // if the dialog wasn't of a custom size we know we can shrink // it if necessary based on sash movement. bool customSize = !computedSize.opEquals(currentSize); data.widthHint = newWidthHint; setLastTreeWidth(newWidthHint); composite_.layout(true); // recompute based on new widget size computedSize = getShell().computeSize(DWT.DEFAULT, DWT.DEFAULT); // if the dialog was of a custom size then increase it only if // necessary. if (customSize) { computedSize.x = Math.max(computedSize.x, currentSize.x); } computedSize.y = Math.max(computedSize.y, currentSize.y); if (computedSize.opEquals(currentSize)) { return; } setShellSize(computedSize.x, computedSize.y); lastShellSize = getShell().getSize(); } }); return sash; } /** * Creates the inner page container. * * @param parent * @return Composite */ protected Composite createPageContainer(Composite parent) { Composite outer = new Composite(parent, DWT.NONE); GridData outerData = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL); outerData.horizontalIndent = IDialogConstants.HORIZONTAL_MARGIN; outer.setLayout(new GridLayout()); outer.setLayoutData(outerData); //Create an outer composite for spacing scrolled = new ScrolledComposite(outer, DWT.V_SCROLL | DWT.H_SCROLL); scrolled.setExpandHorizontal(true); scrolled.setExpandVertical(true); GridData scrolledData = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL); scrolled.setLayoutData(scrolledData); Composite result = new Composite(scrolled, DWT.NONE); GridData resultData = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL); result.setLayout(getPageLayout()); result.setLayoutData(resultData); scrolled.setContent(result); return result; } /** * Return the layout for the composite that contains * the pages. * @return PageLayout * * @since 3.1 */ protected Layout getPageLayout() { return new PageLayout(); } /** * Creates the wizard's title area. * * @param parent * the DWT parent for the title area composite. * @return the created title area composite. */ protected Composite createTitleArea(Composite parent) { // Create the title area which will contain // a title, message, and image. int margins = 2; titleArea = new Composite(parent, DWT.NONE); FormLayout layout = new FormLayout(); layout.marginHeight = 0; layout.marginWidth = margins; titleArea.setLayout(layout); GridData layoutData = new GridData(GridData.FILL_HORIZONTAL); layoutData.verticalAlignment = DWT.TOP; titleArea.setLayoutData(layoutData); // Message label messageArea = new DialogMessageArea(); messageArea.createContents(titleArea); titleArea.addControlListener(new class ControlAdapter { /* (non-Javadoc) * @see dwt.events.ControlAdapter#controlResized(dwt.events.ControlEvent) */ public void controlResized(ControlEvent e) { updateMessage(); } }); IPropertyChangeListener fontListener = new class IPropertyChangeListener { public void propertyChange(PropertyChangeEvent event) { if (JFaceResources.BANNER_FONT.equals(event.getProperty())) { updateMessage(); } if (JFaceResources.DIALOG_FONT.equals(event.getProperty())) { updateMessage(); Font dialogFont = JFaceResources.getDialogFont(); updateTreeFont(dialogFont); Control[] children = (cast(Composite) buttonBar).getChildren(); for (int i = 0; i < children.length; i++) { children[i].setFont(dialogFont); } } } }; titleArea.addDisposeListener(new class(fontListener) DisposeListener { IPropertyChangeListener fontListener_; this(IPropertyChangeListener a){ fontListener_=a; } public void widgetDisposed(DisposeEvent event) { JFaceResources.getFontRegistry().removeListener(fontListener_); } }); JFaceResources.getFontRegistry().addListener(fontListener); messageArea.setTitleLayoutData(createMessageAreaData()); messageArea.setMessageLayoutData(createMessageAreaData()); return titleArea; } /** * Create the layout data for the message area. * * @return FormData for the message area. */ private FormData createMessageAreaData() { FormData messageData = new FormData(); messageData.top = new FormAttachment(0); messageData.bottom = new FormAttachment(100); messageData.right = new FormAttachment(100); messageData.left = new FormAttachment(0); return messageData; } /** * @param parent * the DWT parent for the tree area controls. * @return the new <code>Control</code>. * @since 3.0 */ protected Control createTreeAreaContents(Composite parent) { // Build the tree an put it into the composite. treeViewer = createTreeViewer(parent); treeViewer.setInput(getPreferenceManager()); updateTreeFont(JFaceResources.getDialogFont()); layoutTreeAreaControl(treeViewer.getControl()); return treeViewer.getControl(); } /** * Create a new <code>TreeViewer</code>. * * @param parent * the parent <code>Composite</code>. * @return the <code>TreeViewer</code>. * @since 3.0 */ protected TreeViewer createTreeViewer(Composite parent) { final TreeViewer viewer = new TreeViewer(parent, DWT.NONE); addListeners(viewer); viewer.setLabelProvider(new PreferenceLabelProvider()); viewer.setContentProvider(new PreferenceContentProvider()); return viewer; } /** * Add the listeners to the tree viewer. * @param viewer * * @since 3.1 */ protected void addListeners(TreeViewer viewer) { viewer.addPostSelectionChangedListener(new class(viewer) ISelectionChangedListener { TreeViewer viewer_; this(TreeViewer a){ viewer_=a; } private void handleError() { try { // remove the listener temporarily so that the events caused // by the error handling dont further cause error handling // to occur. viewer_.removePostSelectionChangedListener(this); showPageFlippingAbortDialog(); selectCurrentPageAgain(); clearSelectedNode(); } finally { viewer_.addPostSelectionChangedListener(this); } } public void selectionChanged(SelectionChangedEvent event) { Object selection = cast(Object) getSingleSelection(event.getSelection()); if (cast(IPreferenceNode)selection ) { BusyIndicator.showWhile(getShell().getDisplay(), new class(selection) Runnable { Object selection_; this(Object o){ selection_=o; } public void run() { if (!isCurrentPageValid()) { handleError(); } else if (!showPage(cast(IPreferenceNode) selection_)) { // Page flipping wasn't successful handleError(); } else { // Everything went well lastSuccessfulNode = cast(IPreferenceNode) selection_; } } }); } } }); (cast(Tree) viewer.getControl()).addSelectionListener(new class(viewer) SelectionAdapter { TreeViewer viewer_; this(TreeViewer a){ viewer_=a; } public void widgetDefaultSelected(SelectionEvent event) { ISelection selection = viewer_.getSelection(); if (selection.isEmpty()) { return; } IPreferenceNode singleSelection = getSingleSelection(selection); bool expanded = viewer_.getExpandedState(cast(Object)singleSelection); viewer_.setExpandedState(cast(Object)singleSelection, !expanded); } }); //Register help listener on the tree to use context sensitive help viewer.getControl().addHelpListener(new class HelpListener { public void helpRequested(HelpEvent event) { // call perform help on the current page if (currentPage !is null) { currentPage.performHelp(); } } }); } /** * Find the <code>IPreferenceNode</code> that has data the same id as the * supplied value. * * @param nodeId * the id to search for. * @return <code>IPreferenceNode</code> or <code>null</code> if not * found. */ protected IPreferenceNode findNodeMatching(String nodeId) { List nodes = preferenceManager.getElements(PreferenceManager.POST_ORDER); for (Iterator i = nodes.iterator(); i.hasNext();) { IPreferenceNode node = cast(IPreferenceNode) i.next(); if (node.getId().equals(nodeId)) { return node; } } return null; } /** * Get the last known right side width. * * @return the width. */ protected int getLastRightWidth() { return lastTreeWidth; } /** * Returns the preference mananger used by this preference dialog. * * @return the preference mananger */ public PreferenceManager getPreferenceManager() { return preferenceManager; } /* * (non-Javadoc) * * @see dwtx.jface.preference.IPreferencePageContainer#getPreferenceStore() */ public IPreferenceStore getPreferenceStore() { return preferenceStore; } /** * Get the name of the selected item preference * * @return String */ protected String getSelectedNodePreference() { return lastPreferenceId; } /** * @param selection * the <code>ISelection</code> to examine. * @return the first element, or null if empty. */ protected IPreferenceNode getSingleSelection(ISelection selection) { if (!selection.isEmpty()) { IStructuredSelection structured = cast(IStructuredSelection) selection; if (cast(IPreferenceNode)structured.getFirstElement() ) { return cast(IPreferenceNode) structured.getFirstElement(); } } return null; } /** * @return the <code>TreeViewer</code> for this dialog. * @since 3.3 */ public TreeViewer getTreeViewer() { return treeViewer; } /** * Save the values specified in the pages. * <p> * The default implementation of this framework method saves all pages of * type <code>PreferencePage</code> (if their store needs saving and is a * <code>PreferenceStore</code>). * </p> * <p> * Subclasses may override. * </p> */ protected void handleSave() { Iterator nodes = preferenceManager.getElements(PreferenceManager.PRE_ORDER).iterator(); while (nodes.hasNext()) { IPreferenceNode node = cast(IPreferenceNode) nodes.next(); IPreferencePage page = node.getPage(); if (cast(PreferencePage)page ) { // Save now in case tbe workbench does not shutdown cleanly IPreferenceStore store = (cast(PreferencePage) page).getPreferenceStore(); if (store !is null && store.needsSaving() && cast(IPersistentPreferenceStore)store ) { try { (cast(IPersistentPreferenceStore) store).save(); } catch (IOException e) { String message =JFaceResources.format( "PreferenceDialog.saveErrorMessage", [ page.getTitle(), e.msg ]); //$NON-NLS-1$ Policy.getStatusHandler().show( new Status(IStatus.ERROR, Policy.JFACE, message, e), JFaceResources.getString("PreferenceDialog.saveErrorTitle")); //$NON-NLS-1$ } } } } } /** * Notifies that the window's close button was pressed, the close menu was * selected, or the ESCAPE key pressed. * <p> * The default implementation of this framework method sets the window's * return code to <code>CANCEL</code> and closes the window using * <code>close</code>. Subclasses may extend or reimplement. * </p> */ protected override void handleShellCloseEvent() { // handle the same as pressing cancel cancelPressed(); } /** * Notifies of the pressing of the Help button. * <p> * The default implementation of this framework method calls * <code>performHelp</code> on the currently active page. * </p> */ protected /+override+/ void helpPressed() { if (currentPage !is null) { currentPage.performHelp(); } } /** * Returns whether the current page is valid. * * @return <code>false</code> if the current page is not valid, or or * <code>true</code> if the current page is valid or there is no * current page */ protected bool isCurrentPageValid() { if (currentPage is null) { return true; } return currentPage.isValid(); } /** * @param control * the <code>Control</code> to lay out. * @since 3.0 */ protected void layoutTreeAreaControl(Control control) { GridData gd = new GridData(GridData.FILL_VERTICAL); gd.widthHint = getLastRightWidth(); gd.verticalSpan = 1; control.setLayoutData(gd); } /** * The preference dialog implementation of this <code>Dialog</code> * framework method sends <code>performOk</code> to all pages of the * preference dialog, then calls <code>handleSave</code> on this dialog to * save any state, and then calls <code>close</code> to close this dialog. */ protected override void okPressed() { SafeRunnable.run(new class SafeRunnable { private bool errorOccurred; /* * (non-Javadoc) * * @see dwtx.core.runtime.ISafeRunnable#run() */ public void run() { getButton(IDialogConstants.OK_ID).setEnabled(false); errorOccurred = false; bool hasFailedOK = false; try { // Notify all the pages and give them a chance to abort Iterator nodes = preferenceManager.getElements(PreferenceManager.PRE_ORDER) .iterator(); while (nodes.hasNext()) { IPreferenceNode node = cast(IPreferenceNode) nodes.next(); IPreferencePage page = node.getPage(); if (page !is null) { if (!page.performOk()){ hasFailedOK = true; return; } } } } catch (Exception e) { handleException(e); } finally { //Don't bother closing if the OK failed if(hasFailedOK){ setReturnCode(FAILED); getButton(IDialogConstants.OK_ID).setEnabled(true); //return; } else{ if (!errorOccurred) { //Give subclasses the choice to save the state of the //preference pages. handleSave(); } setReturnCode(OK); close(); } } } /* * (non-Javadoc) * * @see dwtx.core.runtime.ISafeRunnable#handleException(java.lang.Throwable) */ public void handleException(Exception e) { errorOccurred = true; Policy.getLog().log(new Status(IStatus.ERROR, Policy.JFACE, 0, e.toString(), e)); clearSelectedNode(); String message = JFaceResources.getString("SafeRunnable.errorMessage"); //$NON-NLS-1$ Policy.getStatusHandler().show( new Status(IStatus.ERROR, Policy.JFACE, message, e), JFaceResources.getString("Error")); //$NON-NLS-1$ } }); } /** * Selects the page determined by <code>lastSuccessfulNode</code> in the * page hierarchy. */ void selectCurrentPageAgain() { if (lastSuccessfulNode is null) { return; } getTreeViewer().setSelection(new StructuredSelection(cast(Object)lastSuccessfulNode)); currentPage.setVisible(true); } /** * Selects the saved item in the tree of preference pages. If it cannot do * this it saves the first one. */ protected void selectSavedItem() { IPreferenceNode node = findNodeMatching(getSelectedNodePreference()); if (node is null) { IPreferenceNode[] nodes = preferenceManager.getRootSubNodes(); ViewerComparator comparator = getTreeViewer().getComparator(); if (comparator !is null) { comparator.sort(null, arraycast!(Object)(nodes)); } ViewerFilter[] filters = getTreeViewer().getFilters(); for (int i = 0; i < nodes.length; i++) { IPreferenceNode selectedNode = nodes[i]; // See if it passes all filters for (int j = 0; j < filters.length; j++) { if (!filters[j].select(this.treeViewer, cast(Object)preferenceManager .getRoot_package(), cast(Object)selectedNode)) { selectedNode = null; break; } } // if it passes all filters select it if (selectedNode !is null) { node = selectedNode; break; } } } if (node !is null) { getTreeViewer().setSelection(new StructuredSelection(cast(Object)node), true); // Keep focus in tree. See bugs 2692, 2621, and 6775. getTreeViewer().getControl().setFocus(); } } /** * Display the given error message. The currently displayed message is saved * and will be redisplayed when the error message is set to * <code>null</code>. * * @param newErrorMessage * the errorMessage to display or <code>null</code> */ public void setErrorMessage(String newErrorMessage) { if (newErrorMessage is null) { messageArea.clearErrorMessage(); } else { messageArea.updateText(newErrorMessage, IMessageProvider.ERROR); } } /** * Save the last known tree width. * * @param width * the width. */ private void setLastTreeWidth(int width) { lastTreeWidth = width; } /** * Set the message text. If the message line currently displays an error, * the message is stored and will be shown after a call to clearErrorMessage * <p> * Shortcut for <code>setMessage(newMessage, NONE)</code> * </p> * * @param newMessage * the message, or <code>null</code> to clear the message */ public void setMessage(String newMessage) { setMessage(newMessage, IMessageProvider.NONE); } /** * Sets the message for this dialog with an indication of what type of * message it is. * <p> * The valid message types are one of <code>NONE</code>, * <code>INFORMATION</code>,<code>WARNING</code>, or * <code>ERROR</code>. * </p> * <p> * Note that for backward compatibility, a message of type * <code>ERROR</code> is different than an error message (set using * <code>setErrorMessage</code>). An error message overrides the current * message until the error message is cleared. This method replaces the * current message and does not affect the error message. * </p> * * @param newMessage * the message, or <code>null</code> to clear the message * @param newType * the message type * @since 2.0 */ public void setMessage(String newMessage, int newType) { messageArea.updateText(newMessage, newType); } /** * Sets the minimum page size. * * @param minWidth * the minimum page width * @param minHeight * the minimum page height * @see #setMinimumPageSize(Point) */ public void setMinimumPageSize(int minWidth, int minHeight) { minimumPageSize.x = minWidth; minimumPageSize.y = minHeight; } /** * Sets the minimum page size. * * @param size * the page size encoded as <code>new Point(width,height)</code> * @see #setMinimumPageSize(int,int) */ public void setMinimumPageSize(Point size) { minimumPageSize.x = size.x; minimumPageSize.y = size.y; } /** * Sets the preference store for this preference dialog. * * @param store * the preference store * @see #getPreferenceStore */ public void setPreferenceStore(IPreferenceStore store) { Assert.isNotNull(cast(Object)store); preferenceStore = store; } /** * Save the currently selected node. */ private void setSelectedNode() { String storeValue = null; IStructuredSelection selection = cast(IStructuredSelection) getTreeViewer().getSelection(); if (selection.size() is 1) { IPreferenceNode node = cast(IPreferenceNode) selection.getFirstElement(); storeValue = node.getId(); } setSelectedNodePreference(storeValue); } /** * Sets the name of the selected item preference. Public equivalent to * <code>setSelectedNodePreference</code>. * * @param pageId * The identifier for the page * @since 3.0 */ public void setSelectedNode(String pageId) { setSelectedNodePreference(pageId); } /** * Sets the name of the selected item preference. * * @param pageId * The identifier for the page */ protected void setSelectedNodePreference(String pageId) { lastPreferenceId = pageId; } /** * Changes the shell size to the given size, ensuring that it is no larger * than the display bounds. * * @param width * the shell width * @param height * the shell height */ private void setShellSize(int width, int height) { Rectangle preferred = getShell().getBounds(); preferred.width = width; preferred.height = height; getShell().setBounds(getConstrainedShellBounds(preferred)); } /** * Shows the preference page corresponding to the given preference node. * Does nothing if that page is already current. * * @param node * the preference node, or <code>null</code> if none * @return <code>true</code> if the page flip was successful, and * <code>false</code> is unsuccessful */ protected bool showPage(IPreferenceNode node) { if (node is null) { return false; } // Create the page if nessessary if (node.getPage() is null) { createPage(node); } if (node.getPage() is null) { return false; } IPreferencePage newPage = getPage(node); if (newPage is currentPage) { return true; } if (currentPage !is null) { if (!currentPage.okToLeave()) { return false; } } IPreferencePage oldPage = currentPage; currentPage = newPage; // Set the new page's container currentPage.setContainer(this); // Ensure that the page control has been created // (this allows lazy page control creation) if (currentPage.getControl() is null) { bool[1] failed; failed[0] = false; SafeRunnable.run(new class(failed) ISafeRunnable { bool[] failed_; this(bool[] a){ this.failed_=a; } public void handleException(Exception e) { this.failed_[0] = true; } public void run() { createPageControl(currentPage, pageContainer); } }); if (failed[0]) { return false; } // the page is responsible for ensuring the created control is // accessable // via getControl. Assert.isNotNull(currentPage.getControl()); } // Force calculation of the page's description label because // label can be wrapped. Point[1] size; Point failed = new Point(-1, -1); SafeRunnable.run(new class(size,failed) ISafeRunnable { Point[] size_; Point failed_; this(Point[] a,Point b){ size_=a; failed_=b; } public void handleException(Exception e) { size_[0] = failed_; } public void run() { size_[0] = currentPage.computeSize(); } }); if (size[0].opEquals(failed)) { return false; } Point contentSize = size[0]; // Do we need resizing. Computation not needed if the // first page is inserted since computing the dialog's // size is done by calling dialog.open(). // Also prevent auto resize if the user has manually resized Shell shell = getShell(); Point shellSize = shell.getSize(); if (oldPage !is null) { Rectangle rect = pageContainer.getClientArea(); Point containerSize = new Point(rect.width, rect.height); int hdiff = contentSize.x - containerSize.x; int vdiff = contentSize.y - containerSize.y; if ((hdiff > 0 || vdiff > 0) && shellSize.opEquals(lastShellSize)) { hdiff = Math.max(0, hdiff); vdiff = Math.max(0, vdiff); setShellSize(shellSize.x + hdiff, shellSize.y + vdiff); lastShellSize = shell.getSize(); if (currentPage.getControl().getSize().x is 0) { currentPage.getControl().setSize(containerSize); } } else { currentPage.setSize(containerSize); } } scrolled.setMinSize(contentSize); // Ensure that all other pages are invisible // (including ones that triggered an exception during // their creation). Control[] children = pageContainer.getChildren(); Control currentControl = currentPage.getControl(); for (int i = 0; i < children.length; i++) { if (children[i] !is currentControl) { children[i].setVisible(false); } } // Make the new page visible currentPage.setVisible(true); if (oldPage !is null) { oldPage.setVisible(false); } // update the dialog controls update(); return true; } /** * Create the page for the node. * @param node * * @since 3.1 */ protected void createPage(IPreferenceNode node) { node.createPage(); } /** * Get the page for the node. * @param node * @return IPreferencePage * * @since 3.1 */ protected IPreferencePage getPage(IPreferenceNode node) { return node.getPage(); } /** * Shows the "Page Flipping abort" dialog. */ void showPageFlippingAbortDialog() { MessageDialog.openError(getShell(), JFaceResources .getString("AbortPageFlippingDialog.title"), //$NON-NLS-1$ JFaceResources.getString("AbortPageFlippingDialog.message")); //$NON-NLS-1$ } /** * Updates this dialog's controls to reflect the current page. */ protected void update() { // Update the title bar updateTitle(); // Update the message line updateMessage(); // Update the buttons updateButtons(); //Saved the selected node in the preferences setSelectedNode(); firePageChanged(new PageChangedEvent(this, cast(Object)getCurrentPage())); } /* * (non-Javadoc) * * @see dwtx.jface.preference.IPreferencePageContainer#updateButtons() */ public void updateButtons() { okButton.setEnabled(isCurrentPageValid()); } /* * (non-Javadoc) * * @see dwtx.jface.preference.IPreferencePageContainer#updateMessage() */ public void updateMessage() { String message = null; String errorMessage = null; if(currentPage !is null){ message = currentPage.getMessage(); errorMessage = currentPage.getErrorMessage(); } int messageType = IMessageProvider.NONE; if (message !is null && cast(IMessageProvider)currentPage ) { messageType = (cast(IMessageProvider) currentPage).getMessageType(); } if (errorMessage is null){ if (showingError) { // we were previously showing an error showingError = false; } } else { message = errorMessage; messageType = IMessageProvider.ERROR; if (!showingError) { // we were not previously showing an error showingError = true; } } messageArea.updateText(message,messageType); } /* * (non-Javadoc) * * @see dwtx.jface.preference.IPreferencePageContainer#updateTitle() */ public void updateTitle() { if(currentPage is null) { return; } messageArea.showTitle(currentPage.getTitle(), currentPage.getImage()); } /** * Update the tree to use the specified <code>Font</code>. * * @param dialogFont * the <code>Font</code> to use. * @since 3.0 */ protected void updateTreeFont(Font dialogFont) { getTreeViewer().getControl().setFont(dialogFont); } /** * Returns the currentPage. * @return IPreferencePage * @since 3.1 */ protected IPreferencePage getCurrentPage() { return currentPage; } /** * Sets the current page. * @param currentPage * * @since 3.1 */ protected void setCurrentPage(IPreferencePage currentPage) { this.currentPage = currentPage; } /** * Set the treeViewer. * @param treeViewer * * @since 3.1 */ protected void setTreeViewer(TreeViewer treeViewer) { this.treeViewer = treeViewer; } /** * Get the composite that is showing the page. * * @return Composite. * * @since 3.1 */ protected Composite getPageContainer() { return this.pageContainer; } /** * Set the composite that is showing the page. * @param pageContainer Composite * * @since 3.1 */ protected void setPageContainer(Composite pageContainer) { this.pageContainer = pageContainer; } /** * Create the page control for the supplied page. * * @param page - the preference page to be shown * @param parent - the composite to parent the page * * @since 3.1 */ protected void createPageControl(IPreferencePage page, Composite parent) { page.createControl(parent); } /** * @see dwtx.jface.dialogs.IPageChangeProvider#getSelectedPage() * * @since 3.1 */ public Object getSelectedPage() { return cast(Object)getCurrentPage(); } /** * @see dwtx.jface.dialogs.IPageChangeProvider#addPageChangedListener(dwtx.jface.dialogs.IPageChangedListener) * @since 3.1 */ public void addPageChangedListener(IPageChangedListener listener) { pageChangedListeners.add(cast(Object)listener); } /** * @see dwtx.jface.dialogs.IPageChangeProvider#removePageChangedListener(dwtx.jface.dialogs.IPageChangedListener) * @since 3.1 */ public void removePageChangedListener(IPageChangedListener listener) { pageChangedListeners.remove(cast(Object)listener); } /** * Notifies any selection changed listeners that the selected page * has changed. * Only listeners registered at the time this method is called are notified. * * @param event a selection changed event * * @see IPageChangedListener#pageChanged * * @since 3.1 */ protected void firePageChanged(PageChangedEvent event) { Object[] listeners = pageChangedListeners.getListeners(); for (int i = 0; i < listeners.length; i++) { SafeRunnable.run(new class(event,cast(IPageChangedListener) listeners[i]) SafeRunnable { PageChangedEvent event_; IPageChangedListener l; this(PageChangedEvent a,IPageChangedListener b){ event_=a; l =b ; } public void run() { l.pageChanged(event_); } }); } } /* * (non-Javadoc) * @see dwtx.jface.dialogs.Dialog#isResizable() */ protected bool isResizable() { return true; } }