KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > progress > JobErrorDialog


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.ui.internal.progress;
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.ViewerSorter;
37 import org.eclipse.swt.SWT;
38 import org.eclipse.swt.events.DisposeListener;
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.WorkbenchPlugin;
49 import org.eclipse.ui.progress.IProgressConstants;
50
51 /**
52  * A dialog that can display the errors from multiple jobs at once but is
53  * visually optimal for the case of one job (which is the case 99% of the time).
54  */

55 public class JobErrorDialog extends ErrorDialog {
56
57     /*
58      * Preference used to indicate whether the user should be prompted to
59      * confirm the execution of the job's goto action
60      */

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

63     /*
64      * The id of the goto action button
65      */

66     private static final int GOTO_ACTION_ID = IDialogConstants.CLIENT_ID + 1;
67
68     private TableViewer jobListViewer;
69
70     private ErrorInfo selectedError;
71
72     /**
73      * Create a new instance of the receiver.
74      *
75      * @param parentShell
76      * @param title
77      * @param msg
78      * @param errorInfo
79      * @param displayMask
80      */

81     public JobErrorDialog(Shell parentShell, String JavaDoc title, String JavaDoc msg,
82             ErrorInfo errorInfo, int displayMask) {
83         super(parentShell,
84                 title == null ? errorInfo.getJob().getName() : title, msg,
85                 errorInfo.getErrorStatus(), displayMask);
86         setShellStyle(SWT.DIALOG_TRIM | SWT.MODELESS | SWT.RESIZE | SWT.MIN
87                 | getDefaultOrientation()); // Do not want this one to be modal
88
this.selectedError = errorInfo;
89         setBlockOnOpen(false);
90     }
91
92     /**
93      * Method which should be invoked when new errors become available for
94      * display
95      */

96     void refresh() {
97
98         if (AUTOMATED_MODE) {
99             return;
100         }
101
102         // Do not refresh if we are in the process of
103
// opening or shutting down
104
if (dialogArea == null || dialogArea.isDisposed()) {
105             return;
106         }
107
108         if (isMultipleJobErrors()) {
109             if (jobListViewer == null) {
110                 // The job list doesn't exist so create it.
111
setMessage(ProgressMessages.JobErrorDialog_MultipleErrorsMessage);
112                 getShell().setText(
113                         ProgressMessages.JobErrorDialog_MultipleErrorsTitle);
114                 createJobListArea((Composite) dialogArea);
115                 showDetailsArea();
116             }
117             refreshJobList();
118         }
119         updateEnablements();
120     }
121
122     /*
123      * (non-Javadoc)
124      *
125      * @see org.eclipse.jface.dialogs.ErrorDialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
126      */

127     protected void createButtonsForButtonBar(Composite parent) {
128         IAction gotoAction = getGotoAction();
129         String JavaDoc text = null;
130         if (gotoAction != null) {
131             text = gotoAction.getText();
132         }
133         if (text == null) {
134             // Text is set to this initiallybut will be changed for active job
135
text = ProgressMessages.JobErrorDialog_CustomJobText;
136         }
137         createButton(parent, GOTO_ACTION_ID, text, false);
138         super.createButtonsForButtonBar(parent);
139     }
140
141     /*
142      * Update the button enablements
143      */

144     private void updateEnablements() {
145         Button details = getButton(IDialogConstants.DETAILS_ID);
146         if (details != null) {
147             details.setEnabled(selectedError.getErrorStatus().isMultiStatus()
148                     || isMultipleJobErrors());
149         }
150         Button gotoButton = getButton(GOTO_ACTION_ID);
151         if (gotoButton != null) {
152             IAction gotoAction = getGotoAction();
153             boolean hasValidGotoAction = gotoAction != null;
154             String JavaDoc text = gotoButton.getText();
155             String JavaDoc newText = null;
156             if (hasValidGotoAction) {
157                 newText = gotoAction.getText();
158             }
159             if (newText == null) {
160                 hasValidGotoAction = false;
161                 newText = ProgressMessages.JobErrorDialog_CustomJobText;
162             }
163             if (!newText.equals(text)) {
164                 gotoButton.setText(newText);
165             }
166             gotoButton.setEnabled(hasValidGotoAction);
167             gotoButton.setVisible(hasValidGotoAction);
168         }
169     }
170
171     /*
172      * (non-Javadoc)
173      *
174      * @see org.eclipse.jface.dialogs.ErrorDialog#buttonPressed(int)
175      */

176     protected void buttonPressed(int id) {
177         if (id == GOTO_ACTION_ID) {
178             IAction gotoAction = getGotoAction();
179             if (gotoAction != null) {
180                 if (!isMultipleJobErrors() || isPromptToClose()) {
181                     okPressed(); // close the dialog
182
gotoAction.run(); // run the goto action
183
}
184             }
185         }
186         super.buttonPressed(id);
187     }
188
189     /*
190      * Prompt to inform the user that the dialog will close and the errors
191      * cleared.
192      */

193     private boolean isPromptToClose() {
194         IPreferenceStore store = WorkbenchPlugin.getDefault()
195                 .getPreferenceStore();
196         if (!store.contains(PREF_SKIP_GOTO_ACTION_PROMPT)
197                 || !store.getString(PREF_SKIP_GOTO_ACTION_PROMPT).equals(
198                         MessageDialogWithToggle.ALWAYS)) {
199             MessageDialogWithToggle dialog = MessageDialogWithToggle
200                     .openOkCancelConfirm(
201                             getShell(),
202                             ProgressMessages.JobErrorDialog_CloseDialogTitle,
203                             ProgressMessages.JobErrorDialog_CloseDialogMessage,
204                             ProgressMessages.JobErrorDialog_DoNotShowAgainMessage,
205                             false, store, PREF_SKIP_GOTO_ACTION_PROMPT);
206             return dialog.getReturnCode() == OK;
207         }
208         return true;
209     }
210
211     private IAction getGotoAction() {
212         Object JavaDoc property = selectedError.getJob().getProperty(
213                 IProgressConstants.ACTION_PROPERTY);
214         if (property instanceof IAction) {
215             return (IAction) property;
216         }
217         return null;
218     }
219
220     /**
221      * This method sets the message in the message label.
222      *
223      * @param messageString -
224      * the String for the message area
225      */

226     private void setMessage(String JavaDoc messageString) {
227         // must not set null text in a label
228
message = messageString == null ? "" : messageString; //$NON-NLS-1$
229
if (messageLabel == null || messageLabel.isDisposed()) {
230             return;
231         }
232         messageLabel.setText(message);
233     }
234
235     /**
236      * Create an area that allow the user to select one of multiple jobs that
237      * have reported errors
238      *
239      * @param parent -
240      * the parent of the area
241      */

242     private void createJobListArea(Composite parent) {
243         // Display a list of jobs that have reported errors
244
jobListViewer = new TableViewer(parent, SWT.SINGLE | SWT.H_SCROLL
245                 | SWT.V_SCROLL | SWT.BORDER);
246         jobListViewer.setSorter(getViewerSorter());
247         Control control = jobListViewer.getControl();
248         GridData data = new GridData(GridData.FILL_BOTH
249                 | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
250         data.heightHint = convertHeightInCharsToPixels(10);
251         control.setLayoutData(data);
252         initContentProvider();
253         initLabelProvider();
254         jobListViewer
255                 .addSelectionChangedListener(new ISelectionChangedListener() {
256                     public void selectionChanged(SelectionChangedEvent event) {
257                         handleSelectionChange();
258                     }
259                 });
260         applyDialogFont(parent);
261     }
262
263     /*
264      * Return whether there are multiple errors to be displayed
265      */

266     private boolean isMultipleJobErrors() {
267         return getManager().getErrors().size() > 1;
268     }
269
270     /*
271      * Get the notificationManager that this is being created for.
272      */

273     private ErrorNotificationManager getManager() {
274         return ProgressManager.getInstance().errorManager;
275     }
276
277     /**
278      * Return the selected error info.
279      *
280      * @return ErrorInfo
281      */

282     public ErrorInfo getSelectedError() {
283         return selectedError;
284     }
285
286     /**
287      * Return a viewer sorter for looking at the jobs.
288      *
289      * @return ViewerSorter
290      */

291     private ViewerSorter getViewerSorter() {
292         return new ViewerSorter() {
293             /*
294              * (non-Javadoc)
295              *
296              * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer,
297              * java.lang.Object, java.lang.Object)
298              */

299             public int compare(Viewer testViewer, Object JavaDoc e1, Object JavaDoc e2) {
300                 return ((Comparable JavaDoc) e1).compareTo(e2);
301             }
302         };
303     }
304
305     /**
306      * Sets the content provider for the viewer.
307      */

308     protected void initContentProvider() {
309         IContentProvider provider = new IStructuredContentProvider() {
310             /*
311              * (non-Javadoc)
312              *
313              * @see org.eclipse.jface.viewers.IContentProvider#dispose()
314              */

315             public void dispose() {
316                 // Nothing of interest here
317
}
318
319             /*
320              * (non-Javadoc)
321              *
322              * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
323              */

324             public Object JavaDoc[] getElements(Object JavaDoc inputElement) {
325                 return getManager().getErrors().toArray();
326             }
327
328             /*
329              * (non-Javadoc)
330              *
331              * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
332              * java.lang.Object, java.lang.Object)
333              */

334             public void inputChanged(Viewer viewer, Object JavaDoc oldInput,
335                     Object JavaDoc newInput) {
336                 if (newInput != null) {
337                     refreshJobList();
338                 }
339             }
340         };
341         jobListViewer.setContentProvider(provider);
342         jobListViewer.setInput(getManager());
343         jobListViewer.setSelection(new StructuredSelection(selectedError));
344     }
345
346     /**
347      * Refresh the contents of the viewer.
348      */

349     void refreshJobList() {
350         if (jobListViewer != null && !jobListViewer.getControl().isDisposed()) {
351             jobListViewer.refresh();
352             Point newSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
353             getShell().setSize(newSize);
354         }
355         setStatus(selectedError.getErrorStatus());
356     }
357
358     private void initLabelProvider() {
359         ITableLabelProvider provider = new ITableLabelProvider() {
360             Map JavaDoc imageTable = new HashMap JavaDoc();
361
362             /*
363              * (non-Javadoc)
364              *
365              * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
366              */

367             public void addListener(ILabelProviderListener listener) {
368                 // Do nothing
369
}
370
371             /*
372              * (non-Javadoc)
373              *
374              * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
375              */

376             public void dispose() {
377                 if (!imageTable.isEmpty()) {
378                     for (Iterator JavaDoc iter = imageTable.values().iterator(); iter
379                             .hasNext();) {
380                         Image image = (Image) iter.next();
381                         image.dispose();
382                     }
383                 }
384             }
385
386             /*
387              * (non-Javadoc)
388              *
389              * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object,
390              * int)
391              */

392             public Image getColumnImage(Object JavaDoc element, int columnIndex) {
393                 return getIcon(((ErrorInfo) element).getJob());
394             }
395
396             /*
397              * Get the icon for the job. Code copied from NewProgressViewer
398              */

399             private Image getIcon(Job job) {
400                 if (job != null) {
401
402                     Object JavaDoc property = job
403                             .getProperty(IProgressConstants.ICON_PROPERTY);
404
405                     // If we already have an image cached, return it
406
Image im = (Image) imageTable.get(property);
407                     if (im != null) {
408                         return im;
409                     }
410
411                     // Create an image from the job's icon property or family
412
Display display = getShell().getDisplay();
413                     if (property instanceof ImageDescriptor) {
414                         im = ((ImageDescriptor) property).createImage(display);
415                         imageTable.put(property, im); // Cache for disposal
416
} else if (property instanceof URL JavaDoc) {
417                         im = ImageDescriptor.createFromURL((URL JavaDoc) property)
418                                 .createImage(display);
419                         imageTable.put(property, im); // Cache for disposal
420
} else {
421                         im = ProgressManager.getInstance().getIconFor(job);
422                         // No need to cache since the progress manager will
423
}
424                     return im;
425                 }
426                 return null;
427             }
428
429             /*
430              * (non-Javadoc)
431              *
432              * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object,
433              * int)
434              */

435             public String JavaDoc getColumnText(Object JavaDoc element, int columnIndex) {
436                 return ((ErrorInfo) element).getDisplayString();
437             }
438
439             /*
440              * (non-Javadoc)
441              *
442              * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object,
443              * java.lang.String)
444              */

445             public boolean isLabelProperty(Object JavaDoc element, String JavaDoc property) {
446                 return false;
447             }
448
449             /*
450              * (non-Javadoc)
451              *
452              * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
453              */

454             public void removeListener(ILabelProviderListener listener) {
455                 // Do nothing
456
}
457         };
458         jobListViewer.setLabelProvider(provider);
459     }
460
461     /**
462      * Get the single selection. Return null if the selection is not just one
463      * element.
464      *
465      * @return ErrorInfo or <code>null</code>.
466      */

467     private ErrorInfo getSingleSelection() {
468         ISelection rawSelection = jobListViewer.getSelection();
469         if (rawSelection != null
470                 && rawSelection instanceof IStructuredSelection) {
471             IStructuredSelection selection = (IStructuredSelection) rawSelection;
472             if (selection.size() == 1) {
473                 return (ErrorInfo) selection.getFirstElement();
474             }
475         }
476         return null;
477     }
478
479     public boolean close() {
480         Rectangle shellPosition = getShell().getBounds();
481         boolean result = super.close();
482         ProgressManagerUtil.animateDown(shellPosition);
483         return result;
484     }
485
486     /*
487      * (non-Javadoc)
488      *
489      * @see org.eclipse.jface.dialogs.Dialog#initializeBounds()
490      */

491     protected void initializeBounds() {
492         // We need to refesh here instead of in createContents
493
// because the showDetailsArea requires that the content
494
// composite be set
495
refresh();
496         super.initializeBounds();
497         Rectangle shellPosition = getShell().getBounds();
498         ProgressManagerUtil.animateUp(shellPosition);
499     }
500
501     /**
502      * The selection in the multiple job list has changed. Update widget
503      * enablements and repopulate the list.
504      */

505     void handleSelectionChange() {
506         ErrorInfo newSelection = getSingleSelection();
507         if (newSelection != null && newSelection != selectedError) {
508             selectedError = newSelection;
509             setStatus(selectedError.getErrorStatus());
510             updateEnablements();
511             showDetailsArea();
512         }
513     }
514
515     /*
516      * (non-Javadoc)
517      *
518      * @see org.eclipse.jface.dialogs.ErrorDialog#shouldShowDetailsButton()
519      */

520     protected boolean shouldShowDetailsButton() {
521         return true;
522     }
523
524     /*
525      * (non-Javadoc)
526      *
527      * @see org.eclipse.jface.dialogs.ErrorDialog#configureShell(org.eclipse.swt.widgets.Shell)
528      */

529     protected void configureShell(Shell shell) {
530         super.configureShell(shell);
531         shell.addDisposeListener(new DisposeListener() {
532             /* (non-Javadoc)
533              * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
534              */

535             public void widgetDisposed(org.eclipse.swt.events.DisposeEvent e) {
536                 ProgressManager.getInstance().errorManager.dialogClosed();
537             }
538
539         });
540     }
541 }
542
Popular Tags