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