KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > statushandlers > StatusDialog


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.ui.internal.statushandlers;
12
13 import java.net.URL JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.Map JavaDoc;
17
18 import org.eclipse.core.runtime.jobs.Job;
19 import org.eclipse.jface.action.IAction;
20 import org.eclipse.jface.dialogs.ErrorDialog;
21 import org.eclipse.jface.dialogs.IDialogConstants;
22 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
23 import org.eclipse.jface.preference.IPreferenceStore;
24 import org.eclipse.jface.resource.ImageDescriptor;
25 import org.eclipse.jface.viewers.IContentProvider;
26 import org.eclipse.jface.viewers.ILabelProviderListener;
27 import org.eclipse.jface.viewers.ISelection;
28 import org.eclipse.jface.viewers.ISelectionChangedListener;
29 import org.eclipse.jface.viewers.IStructuredContentProvider;
30 import org.eclipse.jface.viewers.IStructuredSelection;
31 import org.eclipse.jface.viewers.ITableLabelProvider;
32 import org.eclipse.jface.viewers.SelectionChangedEvent;
33 import org.eclipse.jface.viewers.StructuredSelection;
34 import org.eclipse.jface.viewers.TableViewer;
35 import org.eclipse.jface.viewers.Viewer;
36 import org.eclipse.jface.viewers.ViewerComparator;
37 import org.eclipse.osgi.util.NLS;
38 import org.eclipse.swt.SWT;
39 import org.eclipse.swt.graphics.Image;
40 import org.eclipse.swt.graphics.Point;
41 import org.eclipse.swt.graphics.Rectangle;
42 import org.eclipse.swt.layout.GridData;
43 import org.eclipse.swt.widgets.Button;
44 import org.eclipse.swt.widgets.Composite;
45 import org.eclipse.swt.widgets.Control;
46 import org.eclipse.swt.widgets.Display;
47 import org.eclipse.swt.widgets.Shell;
48 import org.eclipse.ui.internal.WorkbenchMessages;
49 import org.eclipse.ui.internal.WorkbenchPlugin;
50 import org.eclipse.ui.internal.progress.ProgressManager;
51 import org.eclipse.ui.internal.progress.ProgressManagerUtil;
52 import org.eclipse.ui.internal.progress.ProgressMessages;
53 import org.eclipse.ui.internal.statushandlers.StatusNotificationManager.StatusInfo;
54 import org.eclipse.ui.progress.IProgressConstants;
55 import org.eclipse.ui.statushandlers.StatusAdapter;
56
57 /**
58  * A dialog for displaying
59  *
60  */

61 public class StatusDialog extends ErrorDialog {
62
63     /*
64      * Preference used to indicate whether the user should be prompted to
65      * confirm the execution of the job's goto action
66      */

67     private static final String JavaDoc PREF_SKIP_GOTO_ACTION_PROMPT = "pref_skip_goto_action_prompt"; //$NON-NLS-1$
68

69     /*
70      * The id of the goto action button
71      */

72     private static final int GOTO_ACTION_ID = IDialogConstants.CLIENT_ID + 1;
73
74     private TableViewer statusListViewer;
75
76     private StatusInfo selectedStatus;
77
78     /**
79      * Create a new instance of the receiver.
80      *
81      * @param parentShell
82      * @param msg
83      * @param statusInfo
84      * @param displayMask
85      */

86     public StatusDialog(Shell parentShell, StatusInfo statusInfo,
87             int displayMask, boolean modal) {
88         super(parentShell, (String JavaDoc)statusInfo.getStatus().getProperty(
89                 StatusAdapter.TITLE_PROPERTY), statusInfo.getStatus()
90                 .getStatus().getMessage(), statusInfo.getStatus().getStatus(),
91                 displayMask);
92         setShellStyle(SWT.RESIZE | SWT.MIN | getShellStyle());
93         this.selectedStatus = statusInfo;
94         setBlockOnOpen(false);
95
96         if (!modal) {
97             setShellStyle(~SWT.APPLICATION_MODAL & getShellStyle());
98         }
99
100         String JavaDoc reason = WorkbenchMessages.StatusDialog_checkDetailsMessage;
101         if (statusInfo.getStatus().getStatus().getException() != null) {
102             reason = statusInfo.getStatus().getStatus().getException()
103                     .getMessage() == null ? statusInfo.getStatus().getStatus()
104                     .getException().toString() : statusInfo.getStatus()
105                     .getStatus().getException().getMessage();
106         }
107         this.message = NLS.bind(WorkbenchMessages.StatusDialog_reason,
108                 new Object JavaDoc[] { statusInfo.getDisplayString(), reason });
109     }
110
111     /**
112      * Method which should be invoked when new errors become available for
113      * display
114      */

115     void refresh() {
116
117         if (AUTOMATED_MODE) {
118             return;
119         }
120
121         // Do not refresh if we are in the process of
122
// opening or shutting down
123
if (dialogArea == null || dialogArea.isDisposed()) {
124             return;
125         }
126
127         if (isMultipleStatusDialog()) {
128             if (statusListViewer == null) {
129                 // The job list doesn't exist so create it.
130
setMessage(ProgressMessages.JobErrorDialog_MultipleErrorsMessage);
131                 getShell().setText(
132                         ProgressMessages.JobErrorDialog_MultipleErrorsTitle);
133                 createStatusListArea((Composite) dialogArea);
134                 showDetailsArea();
135             }
136             refreshStatusList();
137         }
138         updateEnablements();
139     }
140
141     /*
142      * (non-Javadoc)
143      *
144      * @see org.eclipse.jface.dialogs.ErrorDialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
145      */

146     protected void createButtonsForButtonBar(Composite parent) {
147         IAction gotoAction = getGotoAction();
148         String JavaDoc text = null;
149         if (gotoAction != null) {
150             text = gotoAction.getText();
151         }
152         if (text == null) {
153             // Text is set to this initiallybut will be changed for active job
154
text = ProgressMessages.JobErrorDialog_CustomJobText;
155         }
156         createButton(parent, GOTO_ACTION_ID, text, false);
157         super.createButtonsForButtonBar(parent);
158     }
159
160     /*
161      * Update the button enablements
162      */

163     private void updateEnablements() {
164         Button details = getButton(IDialogConstants.DETAILS_ID);
165         if (details != null) {
166             details.setEnabled(true);
167         }
168         Button gotoButton = getButton(GOTO_ACTION_ID);
169         if (gotoButton != null) {
170             IAction gotoAction = getGotoAction();
171             boolean hasValidGotoAction = gotoAction != null;
172             String JavaDoc text = gotoButton.getText();
173             String JavaDoc newText = null;
174             if (hasValidGotoAction) {
175                 newText = gotoAction.getText();
176             }
177             if (newText == null) {
178                 hasValidGotoAction = false;
179                 newText = ProgressMessages.JobErrorDialog_CustomJobText;
180             }
181             if (!newText.equals(text)) {
182                 gotoButton.setText(newText);
183             }
184             gotoButton.setEnabled(hasValidGotoAction);
185             gotoButton.setVisible(hasValidGotoAction);
186         }
187     }
188
189     /*
190      * (non-Javadoc)
191      *
192      * @see org.eclipse.jface.dialogs.ErrorDialog#buttonPressed(int)
193      */

194     protected void buttonPressed(int id) {
195         if (id == GOTO_ACTION_ID) {
196             IAction gotoAction = getGotoAction();
197             if (gotoAction != null) {
198                 if (!isMultipleStatusDialog() || isPromptToClose()) {
199                     okPressed(); // close the dialog
200
gotoAction.run(); // run the goto action
201
}
202             }
203         }
204         super.buttonPressed(id);
205     }
206     
207     public boolean isModal()
208     {
209         return ((getShellStyle() & SWT.APPLICATION_MODAL) == SWT.APPLICATION_MODAL);
210     }
211
212     /*
213      * Prompt to inform the user that the dialog will close and the errors
214      * cleared.
215      */

216     private boolean isPromptToClose() {
217         IPreferenceStore store = WorkbenchPlugin.getDefault()
218                 .getPreferenceStore();
219         if (!store.contains(PREF_SKIP_GOTO_ACTION_PROMPT)
220                 || !store.getString(PREF_SKIP_GOTO_ACTION_PROMPT).equals(
221                         MessageDialogWithToggle.ALWAYS)) {
222             MessageDialogWithToggle dialog = MessageDialogWithToggle
223                     .openOkCancelConfirm(
224                             getShell(),
225                             ProgressMessages.JobErrorDialog_CloseDialogTitle,
226                             ProgressMessages.JobErrorDialog_CloseDialogMessage,
227                             ProgressMessages.JobErrorDialog_DoNotShowAgainMessage,
228                             false, store, PREF_SKIP_GOTO_ACTION_PROMPT);
229             return dialog.getReturnCode() == OK;
230         }
231         return true;
232     }
233
234     private IAction getGotoAction() {
235         Object JavaDoc property = null;
236
237         StatusAdapter statusAdapter = selectedStatus.getStatus();
238         Job job = (Job) (statusAdapter.getAdapter(Job.class));
239         if (job != null) {
240             property = job.getProperty(IProgressConstants.ACTION_PROPERTY);
241         }
242
243         if (property instanceof IAction) {
244             return (IAction) property;
245         }
246         return null;
247     }
248
249     /**
250      * This method sets the message in the message label.
251      *
252      * @param messageString -
253      * the String for the message area
254      */

255     private void setMessage(String JavaDoc messageString) {
256         // must not set null text in a label
257
message = messageString == null ? "" : messageString; //$NON-NLS-1$
258
if (messageLabel == null || messageLabel.isDisposed()) {
259             return;
260         }
261         messageLabel.setText(message);
262     }
263
264     /**
265      * Create an area that allow the user to select one of multiple jobs that
266      * have reported errors
267      *
268      * @param parent -
269      * the parent of the area
270      */

271     private void createStatusListArea(Composite parent) {
272         // Display a list of jobs that have reported errors
273
statusListViewer = new TableViewer(parent, SWT.SINGLE | SWT.H_SCROLL
274                 | SWT.V_SCROLL | SWT.BORDER);
275         statusListViewer.setComparator(getViewerComparator());
276         Control control = statusListViewer.getControl();
277         GridData data = new GridData(GridData.FILL_BOTH
278                 | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
279         data.heightHint = convertHeightInCharsToPixels(10);
280         control.setLayoutData(data);
281         initContentProvider();
282         initLabelProvider();
283         statusListViewer
284                 .addSelectionChangedListener(new ISelectionChangedListener() {
285                     public void selectionChanged(SelectionChangedEvent event) {
286                         handleSelectionChange();
287                     }
288                 });
289         applyDialogFont(parent);
290     }
291
292     /*
293      * Return whether there are multiple errors to be displayed
294      */

295     private boolean isMultipleStatusDialog() {
296         return getManager().getErrors().size() > 1;
297     }
298
299     /*
300      * Get the notificationManager that this is being created for.
301      */

302     private StatusNotificationManager getManager() {
303         return StatusNotificationManager.getInstance();
304     }
305
306     /**
307      * Return the selected error info.
308      *
309      * @return ErrorInfo
310      */

311     public StatusInfo getSelectedError() {
312         return selectedStatus;
313     }
314
315     /**
316      * Return a viewer sorter for looking at the jobs.
317      *
318      * @return ViewerSorter
319      */

320     private ViewerComparator getViewerComparator() {
321         return new ViewerComparator() {
322             /*
323              * (non-Javadoc)
324              *
325              * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer,
326              * java.lang.Object, java.lang.Object)
327              */

328             public int compare(Viewer testViewer, Object JavaDoc e1, Object JavaDoc e2) {
329                 return ((Comparable JavaDoc) e1).compareTo(e2);
330             }
331         };
332     }
333
334     /**
335      * Sets the content provider for the viewer.
336      */

337     protected void initContentProvider() {
338         IContentProvider provider = new IStructuredContentProvider() {
339             /*
340              * (non-Javadoc)
341              *
342              * @see org.eclipse.jface.viewers.IContentProvider#dispose()
343              */

344             public void dispose() {
345                 // Nothing of interest here
346
}
347
348             /*
349              * (non-Javadoc)
350              *
351              * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
352              */

353             public Object JavaDoc[] getElements(Object JavaDoc inputElement) {
354                 return getManager().getErrors().toArray();
355             }
356
357             /*
358              * (non-Javadoc)
359              *
360              * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
361              * java.lang.Object, java.lang.Object)
362              */

363             public void inputChanged(Viewer viewer, Object JavaDoc oldInput,
364                     Object JavaDoc newInput) {
365                 if (newInput != null) {
366                     refreshStatusList();
367                 }
368             }
369         };
370         statusListViewer.setContentProvider(provider);
371         statusListViewer.setInput(getManager());
372         statusListViewer.setSelection(new StructuredSelection(selectedStatus));
373     }
374
375     /**
376      * Refresh the contents of the viewer.
377      */

378     void refreshStatusList() {
379         if (statusListViewer != null
380                 && !statusListViewer.getControl().isDisposed()) {
381             statusListViewer.refresh();
382             Point newSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
383             getShell().setSize(newSize);
384         }
385         setStatus(selectedStatus.getStatus().getStatus());
386     }
387
388     private void initLabelProvider() {
389         ITableLabelProvider provider = new ITableLabelProvider() {
390             Map JavaDoc imageTable = new HashMap JavaDoc();
391
392             /*
393              * (non-Javadoc)
394              *
395              * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
396              */

397             public void addListener(ILabelProviderListener listener) {
398                 // Do nothing
399
}
400
401             /*
402              * (non-Javadoc)
403              *
404              * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
405              */

406             public void dispose() {
407                 if (!imageTable.isEmpty()) {
408                     for (Iterator JavaDoc iter = imageTable.values().iterator(); iter
409                             .hasNext();) {
410                         Image image = (Image) iter.next();
411                         image.dispose();
412                     }
413                 }
414             }
415
416             /*
417              * (non-Javadoc)
418              *
419              * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object,
420              * int)
421              */

422             public Image getColumnImage(Object JavaDoc element, int columnIndex) {
423                 if (element != null) {
424                     StatusAdapter statusAdapter = ((StatusInfo) element)
425                             .getStatus();
426                     Job job = (Job) (statusAdapter.getAdapter(Job.class));
427                     if (job != null) {
428                         return getIcon(job);
429                     }
430                 }
431                 return null;
432             }
433
434             /*
435              * Get the icon for the job. Code copied from NewProgressViewer
436              */

437             private Image getIcon(Job job) {
438                 if (job != null) {
439
440                     Object JavaDoc property = job
441                             .getProperty(IProgressConstants.ICON_PROPERTY);
442
443                     // If we already have an image cached, return it
444
Image im = (Image) imageTable.get(property);
445                     if (im != null) {
446                         return im;
447                     }
448
449                     // Create an image from the job's icon property or family
450
Display display = getShell().getDisplay();
451                     if (property instanceof ImageDescriptor) {
452                         im = ((ImageDescriptor) property).createImage(display);
453                         imageTable.put(property, im); // Cache for disposal
454
} else if (property instanceof URL JavaDoc) {
455                         im = ImageDescriptor.createFromURL((URL JavaDoc) property)
456                                 .createImage(display);
457                         imageTable.put(property, im); // Cache for disposal
458
} else {
459                         im = ProgressManager.getInstance().getIconFor(job);
460                         // No need to cache since the progress manager will
461
}
462                     return im;
463                 }
464                 return null;
465             }
466
467             /*
468              * (non-Javadoc)
469              *
470              * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object,
471              * int)
472              */

473             public String JavaDoc getColumnText(Object JavaDoc element, int columnIndex) {
474                 return ((StatusInfo) element).getDisplayString();
475             }
476
477             /*
478              * (non-Javadoc)
479              *
480              * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object,
481              * java.lang.String)
482              */

483             public boolean isLabelProperty(Object JavaDoc element, String JavaDoc property) {
484                 return false;
485             }
486
487             /*
488              * (non-Javadoc)
489              *
490              * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
491              */

492             public void removeListener(ILabelProviderListener listener) {
493                 // Do nothing
494
}
495         };
496         statusListViewer.setLabelProvider(provider);
497     }
498
499     /**
500      * Get the single selection. Return null if the selection is not just one
501      * element.
502      *
503      * @return ErrorInfo or <code>null</code>.
504      */

505     private StatusInfo getSingleSelection() {
506         ISelection rawSelection = statusListViewer.getSelection();
507         if (rawSelection != null
508                 && rawSelection instanceof IStructuredSelection) {
509             IStructuredSelection selection = (IStructuredSelection) rawSelection;
510             if (selection.size() == 1) {
511                 return (StatusInfo) selection.getFirstElement();
512             }
513         }
514         return null;
515     }
516
517     public boolean close() {
518         Rectangle shellPosition = getShell().getBounds();
519         boolean result = super.close();
520         ProgressManagerUtil.animateDown(shellPosition);
521         return result;
522     }
523
524     public int open() {
525         int result = super.open();
526         setStatus(selectedStatus.getStatus().getStatus());
527         return result;
528     }
529
530     /*
531      * (non-Javadoc)
532      *
533      * @see org.eclipse.jface.dialogs.Dialog#initializeBounds()
534      */

535     protected void initializeBounds() {
536         // We need to refesh here instead of in createContents
537
// because the showDetailsArea requires that the content
538
// composite be set
539
refresh();
540         super.initializeBounds();
541         Rectangle shellPosition = getShell().getBounds();
542         ProgressManagerUtil.animateUp(shellPosition);
543     }
544
545     /**
546      * The selection in the multiple job list has changed. Update widget
547      * enablements and repopulate the list.
548      */

549     void handleSelectionChange() {
550         StatusInfo newSelection = getSingleSelection();
551         if (newSelection != null && newSelection != selectedStatus) {
552             selectedStatus = newSelection;
553             setStatus(selectedStatus.getStatus().getStatus());
554             updateEnablements();
555             showDetailsArea();
556         }
557     }
558
559     /*
560      * (non-Javadoc)
561      *
562      * @see org.eclipse.jface.dialogs.ErrorDialog#shouldShowDetailsButton()
563      */

564     protected boolean shouldShowDetailsButton() {
565         return true;
566     }
567 }
568
Popular Tags