001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: * Sebastian Davids <sdavids@gmx.de> - Fix for bug 93353 -
011: * [Dialogs] InternalErrorDialog#buttonPressed should explicitly call super
012: *******************************************************************************/package org.eclipse.ui.internal.ide.dialogs;
013:
014: import java.io.ByteArrayOutputStream;
015: import java.io.IOException;
016: import java.io.PrintStream;
017:
018: import org.eclipse.jface.dialogs.IDialogConstants;
019: import org.eclipse.jface.dialogs.MessageDialog;
020: import org.eclipse.swt.SWT;
021: import org.eclipse.swt.graphics.Image;
022: import org.eclipse.swt.graphics.Point;
023: import org.eclipse.swt.layout.GridData;
024: import org.eclipse.swt.widgets.Button;
025: import org.eclipse.swt.widgets.Composite;
026: import org.eclipse.swt.widgets.Shell;
027: import org.eclipse.swt.widgets.Text;
028:
029: /**
030: * Added a Details button to the MessageDialog to show the exception
031: * stack trace.
032: */
033: public class InternalErrorDialog extends MessageDialog {
034:
035: private Throwable detail;
036:
037: private int detailButtonID = -1;
038:
039: private Text text;
040:
041: //Workaround. SWT does not seem to set the default button if
042: //there is not control with focus. Bug: 14668
043: private int defaultButtonIndex = 0;
044:
045: /**
046: * Size of the text in lines.
047: */
048: private static final int TEXT_LINE_COUNT = 15;
049:
050: /**
051: * Create a new dialog.
052: *
053: * @param parentShell the parent shell
054: * @param dialogTitle the title
055: * @param dialogTitleImage the title image
056: * @param dialogMessage the message
057: * @param detail the error to display
058: * @param dialogImageType the type of image
059: * @param dialogButtonLabels the button labels
060: * @param defaultIndex the default selected button index
061: */
062: public InternalErrorDialog(Shell parentShell, String dialogTitle,
063: Image dialogTitleImage, String dialogMessage,
064: Throwable detail, int dialogImageType,
065: String[] dialogButtonLabels, int defaultIndex) {
066: super (parentShell, dialogTitle, dialogTitleImage,
067: dialogMessage, dialogImageType, dialogButtonLabels,
068: defaultIndex);
069: defaultButtonIndex = defaultIndex;
070: this .detail = detail;
071: setShellStyle(getShellStyle() | SWT.APPLICATION_MODAL);
072: }
073:
074: //Workaround. SWT does not seem to set rigth the default button if
075: //there is not control with focus. Bug: 14668
076: public int open() {
077: create();
078: Button b = getButton(defaultButtonIndex);
079: b.setFocus();
080: b.getShell().setDefaultButton(b);
081: return super .open();
082: }
083:
084: /**
085: * Set the detail button;
086: * @param index the detail button index
087: */
088: public void setDetailButton(int index) {
089: detailButtonID = index;
090: }
091:
092: /* (non-Javadoc)
093: * Method declared on Dialog.
094: */
095: protected void buttonPressed(int buttonId) {
096: if (buttonId == detailButtonID) {
097: toggleDetailsArea();
098: } else {
099: super .buttonPressed(buttonId);
100: }
101: }
102:
103: /**
104: * Toggles the unfolding of the details area. This is triggered by
105: * the user pressing the details button.
106: */
107: private void toggleDetailsArea() {
108: Point windowSize = getShell().getSize();
109: Point oldSize = getContents().computeSize(SWT.DEFAULT,
110: SWT.DEFAULT);
111:
112: if (text != null) {
113: text.dispose();
114: text = null;
115: getButton(detailButtonID).setText(
116: IDialogConstants.SHOW_DETAILS_LABEL);
117: } else {
118: createDropDownText((Composite) getContents());
119: getButton(detailButtonID).setText(
120: IDialogConstants.HIDE_DETAILS_LABEL);
121: }
122:
123: Point newSize = getContents().computeSize(SWT.DEFAULT,
124: SWT.DEFAULT);
125: getShell().setSize(
126: new Point(windowSize.x, windowSize.y
127: + (newSize.y - oldSize.y)));
128: }
129:
130: /**
131: * Create this dialog's drop-down list component.
132: *
133: * @param parent the parent composite
134: */
135: protected void createDropDownText(Composite parent) {
136: // create the list
137: text = new Text(parent, SWT.BORDER | SWT.H_SCROLL
138: | SWT.V_SCROLL);
139: text.setFont(parent.getFont());
140:
141: // print the stacktrace in the text field
142: try {
143: ByteArrayOutputStream baos = new ByteArrayOutputStream();
144: PrintStream ps = new PrintStream(baos);
145: detail.printStackTrace(ps);
146: ps.flush();
147: baos.flush();
148: text.setText(baos.toString());
149: } catch (IOException e) {
150: }
151:
152: GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
153: | GridData.GRAB_HORIZONTAL
154: | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL);
155: data.heightHint = text.getLineHeight() * TEXT_LINE_COUNT;
156: data.horizontalSpan = 2;
157: text.setLayoutData(data);
158: }
159:
160: /**
161: * Convenience method to open a simple Yes/No question dialog.
162: *
163: * @param parent the parent shell of the dialog, or <code>null</code> if none
164: * @param title the dialog's title, or <code>null</code> if none
165: * @param message the message
166: * @param detail the error
167: * @param defaultIndex the default index of the button to select
168: * @return <code>true</code> if the user presses the OK button,
169: * <code>false</code> otherwise
170: */
171: public static boolean openQuestion(Shell parent, String title,
172: String message, Throwable detail, int defaultIndex) {
173: String[] labels;
174: if (detail == null) {
175: labels = new String[] { IDialogConstants.YES_LABEL,
176: IDialogConstants.NO_LABEL };
177: } else {
178: labels = new String[] { IDialogConstants.YES_LABEL,
179: IDialogConstants.NO_LABEL,
180: IDialogConstants.SHOW_DETAILS_LABEL };
181: }
182:
183: InternalErrorDialog dialog = new InternalErrorDialog(parent,
184: title, null, // accept the default window icon
185: message, detail, QUESTION, labels, defaultIndex);
186: if (detail != null) {
187: dialog.setDetailButton(2);
188: }
189: return dialog.open() == 0;
190: }
191:
192: }
|