Updates for 0.9.5
[debian/openrocket] / src / net / sf / openrocket / gui / dialogs / BugReportDialog.java
1 package net.sf.openrocket.gui.dialogs;
2
3 import java.awt.Desktop;
4 import java.awt.Dialog;
5 import java.awt.Dimension;
6 import java.awt.Window;
7 import java.awt.event.ActionEvent;
8 import java.awt.event.ActionListener;
9 import java.io.IOException;
10 import java.io.PrintWriter;
11 import java.io.StringWriter;
12 import java.io.UnsupportedEncodingException;
13 import java.net.URI;
14 import java.net.URISyntaxException;
15 import java.net.URLEncoder;
16 import java.util.SortedSet;
17 import java.util.TreeSet;
18
19 import javax.swing.JButton;
20 import javax.swing.JDialog;
21 import javax.swing.JLabel;
22 import javax.swing.JOptionPane;
23 import javax.swing.JPanel;
24 import javax.swing.JScrollPane;
25 import javax.swing.JTextArea;
26
27 import net.miginfocom.swing.MigLayout;
28 import net.sf.openrocket.communication.BugReporter;
29 import net.sf.openrocket.gui.components.SelectableLabel;
30 import net.sf.openrocket.gui.components.StyledLabel;
31 import net.sf.openrocket.util.BugException;
32 import net.sf.openrocket.util.GUIUtil;
33 import net.sf.openrocket.util.JarUtil;
34 import net.sf.openrocket.util.Prefs;
35
36 public class BugReportDialog extends JDialog {
37         
38         private static final String REPORT_EMAIL = "openrocket-bugs@lists.sourceforge.net";
39         
40
41         public BugReportDialog(Window parent, String labelText, String message) {
42                 super(parent, "Bug report", Dialog.ModalityType.APPLICATION_MODAL);
43                 
44                 JPanel panel = new JPanel(new MigLayout("fill"));
45                 
46                 // Some fscking Swing bug that makes html labels initially way too high
47                 JLabel label = new JLabel(labelText);
48                 Dimension d = label.getPreferredSize();
49                 d.width = 100000;
50                 label.setMaximumSize(d);
51                 panel.add(label, "gapleft para, wrap para");
52
53                 label = new JLabel("<html>If connected to the Internet, you can simply click " +
54                 "<em>Send bug report</em>.");
55                 d = label.getPreferredSize();
56                 d.width = 100000;
57                 label.setMaximumSize(d);
58                 panel.add(label, "gapleft para, wrap");
59                 
60                 panel.add(new JLabel("Otherwise, send the text below to the address: "), 
61                                 "gapleft para, split 2, gapright rel");
62                 panel.add(new SelectableLabel(REPORT_EMAIL), "growx, wrap para");
63                 
64
65                 final JTextArea textArea = new JTextArea(message, 20, 70);
66                 textArea.setEditable(true);
67                 panel.add(new JScrollPane(textArea), "grow, wrap");
68                 
69                 
70                 panel.add(new StyledLabel("The information above may be included in a public " +
71                                 "bug report.  Make sure it does not contain any sensitive information you " +
72                                 "do not want to be made public.", -1), "wrap para");
73                 
74                 
75                 
76                 ////  Close button
77                 JButton close = new JButton("Close");
78                 close.addActionListener(new ActionListener() {
79                         @Override
80                         public void actionPerformed(ActionEvent e) {
81                                 BugReportDialog.this.dispose();
82                         }
83                 });
84                 panel.add(close, "right, sizegroup buttons, split");
85                 
86                 
87                 ////  Mail button
88 //              if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Action.MAIL)) {
89 //                      JButton mail = new JButton("Open email");
90 //                      mail.setToolTipText("Open email client with the suitable email ready.");
91 //                      mail.addActionListener(new ActionListener() {
92 //                              @Override
93 //                              public void actionPerformed(ActionEvent e) {
94 //                                      String text = textArea.getText();
95 //                                      openEmail(text);
96 //                              }
97 //                      });
98 //                      panel.add(mail, "right, sizegroup buttons");
99 //              }
100                 
101                 
102                 ////  Send button
103                 JButton send = new JButton("Send bug report");
104                 send.setToolTipText("Automatically send the bug report to the OpenRocket developers.");
105                 send.addActionListener(new ActionListener() {
106                         @Override
107                         public void actionPerformed(ActionEvent e) {
108                                 String text = textArea.getText();
109                                 try {
110                                         
111                                         BugReporter.sendBugReport(text);
112
113                                         // Success if we came here
114                                         JOptionPane.showMessageDialog(BugReportDialog.this,
115                                                         new Object[] { "Bug report successfully sent.",
116                                                         "Thank you for helping make OpenRocket better!" },
117                                                         "Bug report sent", JOptionPane.INFORMATION_MESSAGE);
118                                         
119                                 } catch (Exception ex) {
120                                         // Sending the message failed.
121                                         JOptionPane.showMessageDialog(BugReportDialog.this,
122                                                         new Object[] { "OpenRocket was unable to send the bug report:",
123                                                         ex.getClass().getSimpleName() + ": " + ex.getMessage(), " ",
124                                                         "Please send the report manually to " + REPORT_EMAIL },
125                                                         "Error sending report", JOptionPane.ERROR_MESSAGE);
126                                 }
127                         }
128                 });
129                 panel.add(send, "right, sizegroup buttons");
130                 
131                 this.add(panel);
132                 
133                 this.validate();
134                 this.pack();
135                 this.pack();
136                 this.setLocationRelativeTo(parent);
137                 
138                 GUIUtil.setDisposableDialogOptions(this, send);
139         }
140
141         
142         
143         /**
144          * Show a general bug report dialog allowing the user to input information about
145          * the bug they encountered.
146          * 
147          * @param parent        the parent window (may be null).
148          */
149         public static void showBugReportDialog(Window parent) {
150
151                 StringBuilder sb = new StringBuilder();
152                 
153                 sb.append("---------- Bug report ----------\n");
154                 sb.append('\n');
155                 sb.append("Include detailed steps on how to trigger the bug:\n");
156                 sb.append('\n');
157                 sb.append("1. \n");
158                 sb.append("2. \n");
159                 sb.append("3. \n");
160                 sb.append('\n');
161                 
162                 sb.append("What does the software do and what in your opinion should it do in the " +
163                                 "case described above:\n");
164                 sb.append('\n');
165                 sb.append('\n');
166                 sb.append('\n');
167                 
168                 sb.append("Include your email address (optional; it helps if we can " +
169                 "contact you in case we need additional information):\n");
170                 sb.append('\n');
171                 sb.append('\n');
172                 sb.append('\n');
173                 
174
175                 sb.append("(Do not modify anything below this line.)\n");
176                 sb.append("---------- System information ----------\n");
177                 addSystemInformation(sb);
178                 sb.append("---------- End of information ----------\n");
179                 sb.append('\n');
180                 
181                 BugReportDialog reportDialog = 
182                         new BugReportDialog(parent,
183                                         "<html><b>You can report a bug in OpenRocket by filling in and submitting " +
184                                         "the form below.</b><br>" +
185                                         "You can also report bugs and include attachments on the project " +
186                                         "web site.", sb.toString());
187                 reportDialog.setVisible(true);
188         }
189         
190         
191         /**
192          * Show a dialog presented when an uncaught exception occurs.
193          * 
194          * @param parent        the parent window (may be null).
195          * @param t                     the thread that encountered the exception (may be null).
196          * @param e                     the exception.
197          */
198         public static void showExceptionDialog(Window parent, Thread t, Throwable e) {
199
200                 StringBuilder sb = new StringBuilder();
201                 
202                 sb.append("---------- Bug report ----------\n");
203                 sb.append('\n');
204                 sb.append("Please include a description about what actions you were " +
205                                 "performing when the exception occurred:\n");
206                 sb.append('\n');
207                 sb.append('\n');
208                 sb.append('\n');
209                 sb.append('\n');
210                 
211
212                 sb.append("Include your email address (optional; it helps if we can " +
213                                 "contact you in case we need additional information):\n");
214                 sb.append('\n');
215                 sb.append('\n');
216                 sb.append('\n');
217                 sb.append('\n');
218
219                 sb.append("(Do not modify anything below this line.)\n");
220                 sb.append("---------- Exception stack trace ----------\n");
221                 StringWriter sw = new StringWriter();
222                 PrintWriter pw = new PrintWriter(sw);
223                 e.printStackTrace(pw);
224                 sb.append(sw.getBuffer());
225                 sb.append('\n');
226                 
227                 
228                 sb.append("---------- Thread information ----------\n");
229                 if (t == null) {
230                         sb.append("Thread is not specified.");
231                 } else {
232                         sb.append(t + "\n");
233                 }
234                 sb.append('\n');
235                 
236                 
237                 sb.append("---------- System information ----------\n");
238                 addSystemInformation(sb);
239                 sb.append("---------- End of information ----------\n");
240                 sb.append('\n');
241                 
242                 BugReportDialog reportDialog = 
243                         new BugReportDialog(parent, "<html><b>Please include a short description about " +
244                                         "what you were doing when the exception occurred.</b>", sb.toString());
245                 reportDialog.setVisible(true);
246         }
247         
248         
249         private static void addSystemInformation(StringBuilder sb) {
250                 sb.append("OpenRocket version: " + Prefs.getVersion() + "\n");
251                 sb.append("OpenRocket source: " + Prefs.getBuildSource() + "\n");
252                 sb.append("OpenRocket location: " + JarUtil.getCurrentJarFile() + "\n");
253                 sb.append("System properties:\n");
254
255                 // Sort the keys
256                 SortedSet<String> keys = new TreeSet<String>();
257                 for (Object key: System.getProperties().keySet()) {
258                         keys.add((String)key);
259                 }
260                 
261                 for (String key: keys) {
262                         String value = System.getProperty(key);
263                         sb.append("  " + key + "=");
264                         if (key.equals("line.separator")) {
265                                 for (char c: value.toCharArray()) {
266                                         sb.append(String.format("\\u%04x", (int)c));
267                                 }
268                         } else {
269                                 sb.append(value);
270                         }
271                         sb.append('\n');
272                 }
273         }
274         
275         
276         
277         /**
278          * Open the default email client with the suitable bug report.
279          * Note that this does not work on some systems even if Desktop.isSupported()
280          * claims so.
281          * 
282          * @param text  the bug report text.
283          * @return              whether opening the client succeeded.
284          */
285         private boolean openEmail(String text) {
286                 String version;
287                 
288                 try {
289                         text = URLEncoder.encode(text, "UTF-8");
290                         version = URLEncoder.encode(Prefs.getVersion(), "UTF-8");
291                 } catch (UnsupportedEncodingException e) {
292                         throw new BugException(e);
293                 }
294                 
295                 
296                 
297                 String mailto = "mailto:" + REPORT_EMAIL
298                         + "?subject=Bug%20report%20for%20OpenRocket%20" + version 
299                         + "?body=" + text;
300                 URI uri;
301                 try {
302                         uri = new URI(mailto);
303                 } catch (URISyntaxException e) {
304                         e.printStackTrace();
305                         return false;
306                 }
307                 
308                 Desktop desktop = Desktop.getDesktop();
309                 try {
310                         desktop.mail(uri);
311                 } catch (IOException e) {
312                         e.printStackTrace();
313                         return false;
314                 }
315                 
316                 return true;
317         }
318         
319 }