KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > search > internal > ui > util > ExtendedDialogWindow


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.search.internal.ui.util;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18
19 import org.eclipse.core.runtime.Assert;
20
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.graphics.Cursor;
23 import org.eclipse.swt.layout.GridData;
24 import org.eclipse.swt.layout.GridLayout;
25 import org.eclipse.swt.widgets.Button;
26 import org.eclipse.swt.widgets.Composite;
27 import org.eclipse.swt.widgets.Control;
28 import org.eclipse.swt.widgets.Display;
29 import org.eclipse.swt.widgets.Label;
30 import org.eclipse.swt.widgets.Shell;
31
32 import org.eclipse.jface.dialogs.ControlEnableState;
33 import org.eclipse.jface.dialogs.IDialogConstants;
34 import org.eclipse.jface.dialogs.MessageDialog;
35 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
36 import org.eclipse.jface.dialogs.TrayDialog;
37 import org.eclipse.jface.operation.IRunnableContext;
38 import org.eclipse.jface.operation.IRunnableWithProgress;
39 import org.eclipse.jface.operation.ModalContext;
40 import org.eclipse.jface.wizard.ProgressMonitorPart;
41
42 import org.eclipse.search.internal.ui.SearchMessages;
43
44
45 public abstract class ExtendedDialogWindow extends TrayDialog implements IRunnableContext {
46     
47     private Control fContents;
48     private Button fCancelButton;
49     private List JavaDoc fActionButtons;
50     // The number of long running operation executed from the dialog.
51
private long fActiveRunningOperations;
52
53     // The progress monitor
54
private boolean fUseEmbeddedProgressMonitorPart;
55     private ProgressMonitorPart fProgressMonitorPart;
56     private MessageDialog fWindowClosingDialog;
57     private static final String JavaDoc FOCUS_CONTROL= "focusControl"; //$NON-NLS-1$
58
private Cursor fWaitCursor;
59     private Cursor fArrowCursor;
60
61
62     public ExtendedDialogWindow(Shell shell) {
63         super(shell);
64         fActionButtons= new ArrayList JavaDoc();
65         
66         setShellStyle(getShellStyle() | SWT.RESIZE);
67     }
68     
69     //---- Hooks to reimplement in subclasses -----------------------------------
70

71     /**
72      * @param enable Use the embedded progress monitor part
73      */

74     public void setUseEmbeddedProgressMonitorPart(boolean enable) {
75         fUseEmbeddedProgressMonitorPart= enable;
76     }
77     
78     /**
79      * Hook called when the user has pressed the button to perform
80      * the dialog's action. If the method returns <code>false</code>
81      * the dialog stays open. Otherwise the dialog is going to be closed.
82      * @param buttonId Id of the button activated
83      * @return If the method returns <code>false</code>
84      * the dialog stays open.
85      */

86     protected boolean performAction(int buttonId) {
87         return true;
88     }
89      
90     /**
91      * Hook called when the user has pressed the button to cancel
92      * the dialog. If the method returns <code>false</code> the dialog
93      * stays open. Otherwise the dialog is going to be closed.
94      * @return If the method returns <code>false</code>
95      * the dialog stays open.
96      */

97     protected boolean performCancel() {
98         return true;
99     }
100      
101     //---- UI creation ----------------------------------------------------------
102

103     /**
104      * Create the page area.
105      * @param parent The parent composite
106      * @return The created control
107      */

108     protected abstract Control createPageArea(Composite parent);
109      
110     /**
111      * Add buttons to the dialog's button bar.
112      *
113      * Subclasses may override.
114      *
115      * @param parent the button bar composite
116      */

117     protected void createButtonsForButtonBar(Composite parent) {
118         fCancelButton= createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
119     }
120     
121     protected Button createActionButton(Composite parent, int id, String JavaDoc label,
122             boolean defaultButton) {
123         Button actionButton= createButton(parent, id, label, defaultButton);
124         fActionButtons.add(actionButton);
125         return actionButton;
126     }
127      
128     /**
129      * Creates the layout of the extended dialog window.
130      * @param parent The parent composite
131      * @return The created control
132      */

133     protected Control createDialogArea(Composite parent) {
134         Composite result= (Composite) super.createDialogArea(parent);
135         
136         fContents= createPageArea(result);
137         fContents.setLayoutData(new GridData(GridData.FILL_BOTH));
138         
139         if (fUseEmbeddedProgressMonitorPart) {
140             // Insert a progress monitor
141
fProgressMonitorPart= new ProgressMonitorPart(result, new GridLayout(), SWT.DEFAULT);
142             fProgressMonitorPart.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
143             fProgressMonitorPart.setVisible(false);
144             applyDialogFont(fProgressMonitorPart);
145         }
146
147         Label separator= new Label(result, SWT.SEPARATOR | SWT.HORIZONTAL);
148         separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
149         
150         return result;
151     }
152
153     protected void buttonPressed(int buttonId) {
154         switch (buttonId) {
155             case IDialogConstants.CANCEL_ID:
156                 if (fActiveRunningOperations == 0)
157                     close();
158                 break;
159             default:
160                 if (performAction(buttonId))
161                     close();
162         }
163     }
164     
165     //---- Setters and Getters --------------------------------------------------
166

167     /**
168      * Set the enable state of the perform action button.
169      * @param state The new state
170      */

171     public void setPerformActionEnabled(boolean state) {
172         for (Iterator JavaDoc buttons = fActionButtons.iterator(); buttons.hasNext(); ) {
173             Button element = (Button) buttons.next();
174             element.setEnabled(state);
175         }
176     }
177
178     //---- Operation stuff ------------------------------------------------------
179

180     
181     /* (non-Javadoc)
182      * @see org.eclipse.jface.operation.IRunnableContext#run(boolean, boolean, org.eclipse.jface.operation.IRunnableWithProgress)
183      */

184     public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
185         // The operation can only be canceled if it is executed in a separate thread.
186
// Otherwise the UI is blocked anyway.
187
Object JavaDoc state= null;
188         try {
189             fActiveRunningOperations++;
190             state= aboutToStart(fork && cancelable);
191             if (fUseEmbeddedProgressMonitorPart) {
192                 ModalContext.run(runnable, fork, fProgressMonitorPart, getShell().getDisplay());
193             } else {
194                 new ProgressMonitorDialog(getShell()).run(fork, cancelable, runnable);
195             }
196         } finally {
197             if (state != null)
198                 stopped(state);
199             fActiveRunningOperations--;
200         }
201     }
202     
203     /**
204      * About to start a long running operation triggered through
205      * the wizard. So show the progress monitor and disable
206      * the wizard.
207      * @param enableCancelButton The cancel button enable state
208      * @return The saved UI state.
209      */

210     protected synchronized Object JavaDoc aboutToStart(boolean enableCancelButton) {
211         HashMap JavaDoc savedState= null;
212         Shell shell= getShell();
213         if (shell != null) {
214             Display d= shell.getDisplay();
215             
216             // Save focus control
217
Control focusControl= d.getFocusControl();
218             if (focusControl != null && focusControl.getShell() != shell)
219                 focusControl= null;
220                 
221             // Set the busy cursor to all shells.
222
fWaitCursor= new Cursor(d, SWT.CURSOR_WAIT);
223             setDisplayCursor(d, fWaitCursor);
224                     
225             // Set the arrow cursor to the cancel component.
226
fArrowCursor= new Cursor(d, SWT.CURSOR_ARROW);
227             fCancelButton.setCursor(fArrowCursor);
228     
229             // Deactivate shell
230
savedState= saveUIState(enableCancelButton);
231             if (focusControl != null)
232                 savedState.put(FOCUS_CONTROL, focusControl);
233                 
234             if (fUseEmbeddedProgressMonitorPart) {
235                 // Attach the progress monitor part to the cancel button
236
fProgressMonitorPart.attachToCancelComponent(fCancelButton);
237                 fProgressMonitorPart.setVisible(true);
238             }
239         }
240         
241         return savedState;
242     }
243     
244     /**
245      * A long running operation triggered through the wizard
246      * was stopped either by user input or by normal end.
247      * @param savedState The saveState returned by <code>aboutToStart</code>.
248      * @see #aboutToStart(boolean)
249      */

250     protected synchronized void stopped(Object JavaDoc savedState) {
251         Assert.isTrue( savedState instanceof HashMap JavaDoc);
252         Shell shell= getShell();
253         if (shell != null) {
254             if (fUseEmbeddedProgressMonitorPart) {
255                 fProgressMonitorPart.setVisible(false);
256                 fProgressMonitorPart.removeFromCancelComponent(fCancelButton);
257             }
258                     
259             HashMap JavaDoc state= (HashMap JavaDoc)savedState;
260             restoreUIState(state);
261     
262             setDisplayCursor(shell.getDisplay(), null);
263             fCancelButton.setCursor(null);
264             fWaitCursor.dispose();
265             fWaitCursor= null;
266             fArrowCursor.dispose();
267             fArrowCursor= null;
268             Control focusControl= (Control)state.get(FOCUS_CONTROL);
269             if (focusControl != null && ! focusControl.isDisposed())
270                 focusControl.setFocus();
271         }
272     }
273     
274     private void setDisplayCursor(Display d, Cursor c) {
275         Shell[] shells= d.getShells();
276         for (int i= 0; i < shells.length; i++)
277             shells[i].setCursor(c);
278     }
279
280     //---- UI state save and restoring ---------------------------------------------
281

282     private void restoreUIState(HashMap JavaDoc state) {
283         restoreEnableState(fCancelButton, state);
284         for (Iterator JavaDoc actionButtons = fActionButtons.iterator(); actionButtons.hasNext(); ) {
285             Button button = (Button) actionButtons.next();
286             restoreEnableState(button, state);
287         }
288         ControlEnableState pageState= (ControlEnableState)state.get("tabForm"); //$NON-NLS-1$
289
pageState.restore();
290     }
291     
292     /*
293      * Restores the enable state of the given control.
294      */

295     protected void restoreEnableState(Control w, HashMap JavaDoc h) {
296         if (!w.isDisposed()) {
297             Boolean JavaDoc b= (Boolean JavaDoc)h.get(w);
298             if (b != null)
299                 w.setEnabled(b.booleanValue());
300         }
301     }
302     
303     private HashMap JavaDoc saveUIState(boolean keepCancelEnabled) {
304         HashMap JavaDoc savedState= new HashMap JavaDoc(10);
305         saveEnableStateAndSet(fCancelButton, savedState, keepCancelEnabled);
306         for (Iterator JavaDoc actionButtons = fActionButtons.iterator(); actionButtons.hasNext(); ) {
307             Button button = (Button) actionButtons.next();
308             saveEnableStateAndSet(button, savedState, false);
309         }
310         savedState.put("tabForm", ControlEnableState.disable(fContents)); //$NON-NLS-1$
311

312         return savedState;
313     }
314     
315     private void saveEnableStateAndSet(Control w, HashMap JavaDoc h, boolean enabled) {
316         if (!w.isDisposed()) {
317             h.put(w, new Boolean JavaDoc(w.isEnabled()));
318             w.setEnabled(enabled);
319         }
320     }
321
322     protected void handleShellCloseEvent() {
323         if (okToClose())
324             super.handleShellCloseEvent();
325     }
326
327     /**
328      * The dialog is going to be closed. Check if there is a running
329      * operation. If so, post an alert saying that the wizard can't
330      * be closed.
331      * @return If false is returned, the dialog should stay open
332      */

333     public boolean okToClose() {
334         if (fActiveRunningOperations > 0) {
335             synchronized (this) {
336                 fWindowClosingDialog= createClosingDialog();
337             }
338             fWindowClosingDialog.open();
339             synchronized (this) {
340                 fWindowClosingDialog= null;
341             }
342             return false;
343         }
344         return true;
345     }
346     
347     private MessageDialog createClosingDialog() {
348         MessageDialog result=
349             new MessageDialog(
350                 getShell(),
351                 SearchMessages.SearchDialogClosingDialog_title,
352                 null,
353                 SearchMessages.SearchDialogClosingDialog_message,
354                 MessageDialog.QUESTION,
355                 new String JavaDoc[] {IDialogConstants.OK_LABEL},
356                 0);
357         return result;
358     }
359
360     /**
361      * @return Returns the cancel component that is to be used to cancel
362      * a long running operation.
363      */

364     protected Control getCancelComponent() {
365         return fCancelButton;
366     }
367 }
368
Popular Tags