1 package com.hammurapi.jcapture;
2 
3 import java.awt.BorderLayout;
4 import java.awt.Dimension;
5 import java.awt.GridBagConstraints;
6 import java.awt.GridBagLayout;
7 import java.awt.Insets;
8 import java.awt.event.ActionEvent;
9 import java.awt.event.ActionListener;
10 import java.awt.event.ComponentEvent;
11 import java.awt.event.ComponentListener;
12 import java.io.File;
13 import java.io.FileInputStream;
14 import java.io.FileOutputStream;
15 
16 import javax.swing.JButton;
17 import javax.swing.JFrame;
18 import javax.swing.JOptionPane;
19 import javax.swing.JPanel;
20 import javax.swing.SwingWorker;
21 import javax.swing.WindowConstants;
22 import javax.swing.border.LineBorder;
23 
24 import netscape.javascript.JSObject;
25 
26 import org.apache.http.HttpResponse;
27 import org.apache.http.HttpStatus;
28 
29 public class RecordingControlsFrame extends javax.swing.JFrame {
30 	private static final String RESUME_TEXT = "Resume";
31 	private static final String PAUSE_TEXT = "Pause";
32 	private JButton pauseButton;
33 	private JButton cancelButton;
34 	private JButton stopButton;
35 	private ScreenRecorder screenRecorder;
36 	private CaptureFrame captureFrame;
37 
RecordingControlsFrame(final CaptureFrame captureFrame, final JFrame[] borderFrames)38 	public RecordingControlsFrame(final CaptureFrame captureFrame, final JFrame[] borderFrames) {
39 		super("jCapture recording");
40 		setIconImage(captureFrame.getIconImage());
41 		this.captureFrame = captureFrame;
42 
43 		setUndecorated(true);
44 		setAlwaysOnTop(!getBounds().intersects(captureFrame.getBounds()));
45 
46     	addComponentListener(new ComponentListener() {
47 
48 			@Override
49 			public void componentShown(ComponentEvent e) {
50 				for (JFrame bf: borderFrames) {
51 					if (bf!=null) {
52 						bf.setVisible(true);
53 					}
54 				}
55 			}
56 
57 			@Override
58 			public void componentResized(ComponentEvent e) {
59 				// TODO Auto-generated method stub
60 
61 			}
62 
63 			@Override
64 			public void componentMoved(ComponentEvent e) {
65 				// TODO Auto-generated method stub
66 
67 			}
68 
69 			@Override
70 			public void componentHidden(ComponentEvent e) {
71 				for (JFrame bf: borderFrames) {
72 					if (bf!=null) {
73 						bf.setVisible(false);
74 					}
75 				}
76 			}
77 		});
78 
79 		JPanel contentPanel = new JPanel();
80 		contentPanel.setBorder(new LineBorder(new java.awt.Color(0, 0, 0), 1, false));
81 		getContentPane().add(contentPanel, BorderLayout.CENTER);
82 
83 		GridBagLayout thisLayout = new GridBagLayout();
84 		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
85 		thisLayout.rowWeights = new double[] { 0.0, 0.1, 0.0 };
86 		thisLayout.rowHeights = new int[] { 7, 7, 7 };
87 		thisLayout.columnWeights = new double[] { 0.0, 0.1, 0.0, 0.1, 0.0, 0.1,	0.0 };
88 		thisLayout.columnWidths = new int[] { 7, 20, 7, 20, 7, 7, 7 };
89 		contentPanel.setLayout(thisLayout);
90 
91 		pauseButton = new JButton();
92 		contentPanel.add(pauseButton, new GridBagConstraints(1, 1, 1, 1, 0.0,
93 				0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
94 				new Insets(0, 0, 0, 0), 0, 0));
95 		pauseButton.setText(PAUSE_TEXT);
96 		pauseButton.addActionListener(new ActionListener() {
97 			public void actionPerformed(ActionEvent evt) {
98 				try {
99 					if (PAUSE_TEXT.equals(pauseButton.getText())) {
100 						screenRecorder.stop();
101 						pauseButton.setText(RESUME_TEXT);
102 					} else {
103 						screenRecorder.start();
104 						pauseButton.setText(PAUSE_TEXT);
105 					}
106 				} catch (Exception e) {
107 					e.printStackTrace();
108 					JOptionPane.showMessageDialog(RecordingControlsFrame.this,
109 							e.toString(), "Error pausing/resuming recording",
110 							JOptionPane.ERROR_MESSAGE);
111 				}
112 			}
113 		});
114 
115 		stopButton = new JButton();
116 		contentPanel.add(stopButton, new GridBagConstraints(3, 1, 1, 1, 0.0,
117 				0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
118 				new Insets(0, 0, 0, 0), 0, 0));
119 		stopButton.setText("Stop");
120 		stopButton.addActionListener(new ActionListener() {
121 			public void actionPerformed(ActionEvent evt) {
122 
123 				pauseButton.setEnabled(false);
124 				stopButton.setEnabled(false);
125 				cancelButton.setEnabled(false);
126 
127 				SwingWorker<Movie, Long> task = new SwingWorker<Movie, Long>() {
128 
129 					@Override
130 					protected Movie doInBackground() throws Exception {
131 						screenRecorder.stop();
132 						return screenRecorder.getMovie();
133 					}
134 
135 					@Override
136 					protected void done() {
137 						try {
138 							final Movie movie = get();
139 							if (movie!=null) {
140 								if (JOptionPane.showConfirmDialog(RecordingControlsFrame.this, "Would you like to edit the movie before uploading?", "Edit movie?", JOptionPane.YES_NO_OPTION)==JOptionPane.YES_OPTION) {
141 									new MovieEditorDialog(
142 											RecordingControlsFrame.this,
143 											movie,
144 											captureFrame.getCaptureConfig().getBackgroundProcessor(),
145 											captureFrame.getCaptureConfig().getInactivityInterval(),
146 											captureFrame.getCaptureConfig().getImageFormat());
147 								} else {
148 									uploadMovie(movie);
149 								}
150 							} else {
151 								JOptionPane.showMessageDialog(
152 										RecordingControlsFrame.this,
153 										"Recording discarded",
154 										"Saving recording",
155 										JOptionPane.INFORMATION_MESSAGE);
156 								RecordingControlsFrame.this.setVisible(false);
157 							}
158 						} catch (Exception e) {
159 							e.printStackTrace();
160 							JOptionPane.showMessageDialog(
161 									RecordingControlsFrame.this, e.toString(),
162 									"Error saving recording",
163 									JOptionPane.ERROR_MESSAGE);
164 							RecordingControlsFrame.this.setVisible(false);
165 						}
166 					}
167 
168 				};
169 
170 				task.execute();
171 
172 			}
173 		});
174 
175 		cancelButton = new JButton();
176 		contentPanel.add(cancelButton, new GridBagConstraints(5, 1, 1, 1, 0.0,
177 				0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
178 				new Insets(0, 0, 0, 0), 0, 0));
179 		cancelButton.setText("Cancel");
180 		cancelButton.addActionListener(new ActionListener() {
181 			public void actionPerformed(ActionEvent evt) {
182 				if (JOptionPane.showConfirmDialog(RecordingControlsFrame.this, "Are you sure you want to discard the recording?", "Confirm discarding movie", JOptionPane.YES_NO_OPTION)==JOptionPane.YES_OPTION) {;
183 					try {
184 						screenRecorder.stop();
185 					} catch (Exception e) {
186 						e.printStackTrace();
187 						JOptionPane.showMessageDialog(RecordingControlsFrame.this,
188 								e.toString(), "Error cancelling recording",
189 								JOptionPane.ERROR_MESSAGE);
190 					} finally {
191 						RecordingControlsFrame.this.setVisible(false);
192 						captureFrame.setVisible(true);
193 					}
194 				}
195 			}
196 		});
197 
198 		pack();
199 		this.setSize(301, 40);
200 		captureFrame.getCaptureConfig().setParentComponent(this);
201 		try {
202 			screenRecorder = new ScreenRecorder(captureFrame.getCaptureConfig(), captureFrame.getApplet());
203 		} catch (Exception e) {
204 			e.printStackTrace();
205 			JOptionPane.showMessageDialog(this, e.toString(), "Error starting recording", JOptionPane.ERROR_MESSAGE);
206 			setVisible(false);
207 		}
208 
209 	}
210 
211 	/**
212 	 * Asks for file name and uploads the movie.
213 	 * @param movie
214 	 */
uploadMovie(final Movie movie)215 	void uploadMovie(final Movie movie) {
216 		try {
217 			if (movie!=null) {
218 
219 				final String fileName = JOptionPane.showInputDialog(
220 						RecordingControlsFrame.this,
221 						"Upload as",
222 						captureFrame.getApplet().getParameter("pageName")+
223 						"-recording-"+
224 								captureFrame.getDatePrefix()+
225 								"-" + captureFrame.nextCounter() +"."+captureFrame.getCaptureConfig().getEncoder().getFileExtension());
226 
227 				if (fileName!=null) {
228 					// Uploading
229 					SwingWorker<Dimension, Long> task = new SwingWorker<Dimension, Long>() {
230 
231 						@Override
232 						protected Dimension doInBackground() throws Exception {
233 
234 							File savedTo = null;
235 
236 							try {
237 								// encode and upload
238 								File tmpFile = File.createTempFile("jCaptureMovie", "."+captureFrame.getCaptureConfig().getEncoder().getFileExtension());
239 								FileOutputStream out = new FileOutputStream(tmpFile);
240 								Dimension dimension = captureFrame.getCaptureConfig().getEncoder().encode(captureFrame.getCaptureConfig(), movie, out);
241 								if (dimension==null) {
242 									return null;
243 								}
244 								out.close();
245 								savedTo = tmpFile;
246 
247 								HttpResponse iResponse = captureFrame.getApplet().post(
248 										RecordingControlsFrame.this,
249 										new FileInputStream(tmpFile),
250 										tmpFile.length(),
251 										fileName,
252 										"application/octet-stream");
253 
254 								if (iResponse!=null) {
255 									System.out.println("Response status line: "+iResponse.getStatusLine());
256 									if (iResponse.getStatusLine().getStatusCode()!=HttpStatus.SC_OK) {
257 								    	errorMessage = iResponse.getStatusLine();
258 								    	errorTitle = "Error saving recording";
259 								    	return null;
260 									}
261 								}
262 								if (!tmpFile.delete()) {
263 									tmpFile.deleteOnExit();
264 								}
265 								return dimension;
266 							} catch (Error e) {
267 								errorMessage=e.toString();
268 								if (savedTo!=null) {
269 									errorMessage=errorMessage + ",\n recording was saved to "+savedTo.getAbsolutePath();
270 								}
271 								errorTitle = "Upload error";
272 								e.printStackTrace();
273 								return null;
274 							}
275 						}
276 
277 						private Object errorMessage;
278 						private String errorTitle;
279 
280 						protected void done() {
281 							try {
282 								Dimension dimension = get();
283 								if (dimension!=null) {
284 									JSObject window = JSObject.getWindow(captureFrame.getApplet());
285 									String toEval = "insertAtCarret('"+captureFrame.getApplet().getParameter("edid")+"','{{:"+fileName+"?"+dimension.width+"x"+dimension.height+"|}}')";
286 									System.out.println("Evaluating: "+toEval);
287 									window.eval(toEval);
288 								} else {
289 							    	JOptionPane.showMessageDialog(
290 							    			RecordingControlsFrame.this,
291 											errorMessage,
292 											errorTitle,
293 											JOptionPane.ERROR_MESSAGE);
294 								}
295 							} catch (Exception e) {
296 								e.printStackTrace();
297 						    	JOptionPane.showMessageDialog(
298 						    			RecordingControlsFrame.this,
299 										e.toString(),
300 										"Exception",
301 										JOptionPane.ERROR_MESSAGE);
302 							}
303 						};
304 
305 					};
306 
307 					task.execute();
308 				}
309 			} else {
310 				JOptionPane.showMessageDialog(
311 						RecordingControlsFrame.this,
312 						"Recording discarded",
313 						"Saving recording",
314 						JOptionPane.INFORMATION_MESSAGE);
315 			}
316 		} finally {
317 			RecordingControlsFrame.this.setVisible(false);
318 		}
319 	}
320 
321 }
322