Improved support for comment folding
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.quantum.sql / src / com / quantum / ui / dialog / ExceptionDisplayDialog.java
1 package com.quantum.ui.dialog;
2
3 import com.quantum.Messages;
4
5 import org.eclipse.jface.dialogs.Dialog;
6 import org.eclipse.jface.dialogs.IDialogConstants;
7 import org.eclipse.swt.SWT;
8 import org.eclipse.swt.graphics.Point;
9 import org.eclipse.swt.layout.GridData;
10 import org.eclipse.swt.layout.GridLayout;
11 import org.eclipse.swt.widgets.Button;
12 import org.eclipse.swt.widgets.Composite;
13 import org.eclipse.swt.widgets.Control;
14 import org.eclipse.swt.widgets.Label;
15 import org.eclipse.swt.widgets.Shell;
16 import org.eclipse.swt.widgets.Text;
17
18 /**
19  * @author BC
20  */
21 public class ExceptionDisplayDialog extends Dialog {
22
23     private Control detailsArea;
24     private Throwable throwable;
25     private String message;
26
27     /**
28      * @param parentShell
29      */
30     public ExceptionDisplayDialog(Shell parentShell, Throwable throwable) {
31         super(parentShell);
32         this.throwable = throwable;
33     }
34
35     /**
36      * The Details button.
37      */
38     private Button detailsButton;
39
40     /**
41      * The title of the dialog.
42      */
43     private String title;
44
45     /**
46      * Indicates whether the error details viewer is currently created.
47      */
48     private boolean detailsShown = false;
49
50     /**
51      * Creates an error dialog.
52      * Note that the dialog will have no visual representation (no widgets)
53      * until it is told to open.
54      * <p>
55      * Normally one should use <code>openError</code> to create and open one of these.
56      * This constructor is useful only if the error object being displayed contains child
57      * items <it>and</it> you need to specify a mask which will be used to filter the
58      * displaying of these children.
59      * </p>
60      *
61      * @param parentShell the shell under which to create this dialog
62      * @param dialogTitle the title to use for this dialog,
63      *   or <code>null</code> to indicate that the default title should be used
64      * @param message the message to show in this dialog, 
65      *   or <code>null</code> to indicate that the error's message should be shown
66      *   as the primary message
67      * @param status the error to show to the user
68      * @param displayMask the mask to use to filter the displaying of child items,
69      *   as per <code>IStatus.matches</code>
70      * @see org.eclipse.core.runtime.IStatus#matches(int)
71      */
72     public ExceptionDisplayDialog(
73         Shell parentShell,
74         String dialogTitle,
75         String message,
76         Throwable throwable) {
77         super(parentShell);
78         
79         this.title = dialogTitle;
80         this.message = message;
81         this.throwable = throwable;
82
83         setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL);
84     }
85
86     /* (non-Javadoc)
87      * Method declared on Dialog.
88      * Handles the pressing of the Ok or Details button in this dialog.
89      * If the Ok button was pressed then close this dialog.  If the Details
90      * button was pressed then toggle the displaying of the error details area.
91      * Note that the Details button will only be visible if the error being
92      * displayed specifies child details.
93      */
94     protected void buttonPressed(int id) {
95         if (id == IDialogConstants.DETAILS_ID) {
96             // was the details button pressed?
97             toggleDetailsArea();
98         } else {
99             super.buttonPressed(id);
100         }
101     }
102     /* (non-Javadoc)
103      * Method declared in Window.
104      */
105     protected void configureShell(Shell shell) {
106         super.configureShell(shell);
107         shell.setText(title);
108     }
109     /* (non-Javadoc)
110      * Method declared on Dialog.
111      */
112     protected void createButtonsForButtonBar(Composite parent) {
113         // create OK and Details buttons
114         createButton(
115             parent,
116             IDialogConstants.OK_ID,
117             IDialogConstants.OK_LABEL,
118             true);
119         this.detailsButton =
120             createButton(
121                 parent,
122                 IDialogConstants.DETAILS_ID,
123                 IDialogConstants.SHOW_DETAILS_LABEL,
124                 false);
125     }
126
127     protected Control createDialogArea(Composite parent) {
128
129         // create a composite with standard margins and spacing
130         Composite composite = new Composite(parent, SWT.NONE);
131         GridLayout layout = new GridLayout();
132         layout.marginHeight =
133             convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
134         layout.marginWidth =
135             convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
136         layout.verticalSpacing =
137             convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
138         layout.horizontalSpacing =
139             convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
140         composite.setLayout(layout);
141         GridData childData = new GridData(GridData.FILL_BOTH);
142         childData.horizontalSpan = 2;
143         composite.setLayoutData(childData);
144         composite.setFont(parent.getFont());
145
146         Label label = new Label(composite, 0);
147         label.setText(this.message);
148         label.setFont(parent.getFont());
149         
150         
151         GridData full = new GridData();
152         full.horizontalAlignment = GridData.FILL;
153         full.verticalAlignment = GridData.FILL;
154         full.heightHint = convertHeightInCharsToPixels(3);
155         full.widthHint = convertWidthInCharsToPixels(60);
156         label.setLayoutData(full);
157
158         return composite;
159
160     }
161
162     /**
163      * Create the expandable details arae.
164      *
165      * @param parent the parent composite
166      * @return the details text control
167      */
168     protected Control createDetailsArea(Composite parent) {
169         
170         // create a composite with standard margins and spacing
171         Composite composite = new Composite(parent, SWT.NONE);
172         GridLayout layout = new GridLayout();
173         layout.marginHeight =
174             convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
175         layout.marginWidth =
176             convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
177         layout.verticalSpacing =
178             convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
179         layout.horizontalSpacing =
180             convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
181         composite.setLayout(layout);
182         GridData childData = new GridData(GridData.FILL_BOTH);
183         childData.horizontalSpan = 2;
184         composite.setLayoutData(childData);
185         composite.setFont(parent.getFont());
186
187         Label label = new Label(composite, 0);
188         label.setText(Messages.getString("ExceptionDisplayDialog.stackTrace"));
189         label.setFont(parent.getFont());
190         
191         GridData full = new GridData();
192         full.horizontalAlignment = GridData.FILL;
193         full.verticalAlignment = GridData.FILL;
194         full.heightHint = convertHeightInCharsToPixels(3);
195         full.widthHint = convertWidthInCharsToPixels(60);
196         label.setLayoutData(full);
197
198         Text text =
199             new Text(
200                 composite,
201                 SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
202
203         text.setText(this.throwable.getLocalizedMessage());
204
205         GridData data =
206             new GridData(
207                 GridData.HORIZONTAL_ALIGN_FILL
208                     | GridData.GRAB_HORIZONTAL
209                     | GridData.VERTICAL_ALIGN_FILL
210                     | GridData.GRAB_VERTICAL);
211         data.heightHint = convertHeightInCharsToPixels(8);
212         text.setLayoutData(data);
213         text.setFont(parent.getFont());
214
215         this.detailsShown = true;
216         return composite;
217     }
218     /**
219      * Opens an error dialog to display the given error.  Use this method if the
220      * error object being displayed contains child items <it>and</it> you wish to
221      * specify a mask which will be used to filter the displaying of these
222      * children.  The error dialog will only be displayed if there is at
223      * least one child status matching the mask.
224      *
225      * @param parentShell - 
226      *   the parent shell of the dialog, or <code>null</code> if none
227      * @param title the title to use for this dialog,
228      *   or <code>null</code> to indicate that the default title should be used
229      * @param message the message to show in this dialog, 
230      *   or <code>null</code> to indicate that the error's message should be shown
231      *   as the primary message
232      *   as per <code>IStatus.matches</code>
233      * @return the code of the button that was pressed that resulted in this dialog
234      *     closing.  This will be <code>Dialog.OK</code> if the OK button was 
235      *     pressed, or <code>Dialog.CANCEL</code> if this dialog's close window 
236      *     decoration or the ESC key was used.
237      * @see org.eclipse.core.runtime.IStatus#matches(int)
238      */
239     public static int openError(
240         Shell parentShell,
241         String title,
242         String message,
243         Throwable throwable) {
244             
245         if (title == null) {
246             title = Messages.getString(ExceptionDisplayDialog.class.getName() +
247                 "." + throwable.getClass().getName() + ".title");
248         }
249         if (message == null) {
250             message = Messages.getString(ExceptionDisplayDialog.class.getName() +
251                 "." + throwable.getClass().getName() + ".message");
252         }
253         ExceptionDisplayDialog dialog =
254             new ExceptionDisplayDialog(parentShell, title, message, throwable);
255         return dialog.open();
256     }
257
258     /**
259      * Toggles the unfolding of the details area.  This is triggered by
260      * the user pressing the details button.
261      */
262     private void toggleDetailsArea() {
263         Point windowSize = getShell().getSize();
264         Point oldSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
265
266         if (this.detailsShown) {
267             this.detailsArea.dispose();
268             this.detailsShown = false;
269             detailsButton.setText(IDialogConstants.SHOW_DETAILS_LABEL);
270         } else {
271             this.detailsArea = createDetailsArea((Composite) getContents());
272             detailsButton.setText(IDialogConstants.HIDE_DETAILS_LABEL);
273         }
274
275         Point newSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
276
277         getShell().setSize(
278             new Point(windowSize.x, windowSize.y + (newSize.y - oldSize.y)));
279
280     }
281 }