source: trunk/packages/invirt-vnc-client/RecordingFrame.java @ 2170

Last change on this file since 2170 was 1334, checked in by broder, 16 years ago

sipb-xen-vnc-client -> invirt-vnc-client

File size: 8.1 KB
RevLine 
[66]1//
2//  Copyright (C) 2002 Constantin Kaplinsky.  All Rights Reserved.
3//
4//  This is free software; you can redistribute it and/or modify
5//  it under the terms of the GNU General Public License as published by
6//  the Free Software Foundation; either version 2 of the License, or
7//  (at your option) any later version.
8//
9//  This software is distributed in the hope that it will be useful,
10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12//  GNU General Public License for more details.
13//
14//  You should have received a copy of the GNU General Public License
15//  along with this software; if not, write to the Free Software
16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17//  USA.
18//
19
20//
21// Recording frame. It allows to control recording RFB sessions into
22// FBS (FrameBuffer Stream) files.
23//
24
25import java.io.*;
26import java.awt.*;
27import java.awt.event.*;
28
29class RecordingFrame extends Frame
30  implements WindowListener, ActionListener {
31
32  boolean recording;
33
34  TextField fnameField;
35  Button browseButton;
36
37  Label statusLabel;
38
39  Button recordButton, nextButton, closeButton;
40  VncViewer viewer;
41
42  //
43  // Check if current security manager allows to create a
44  // RecordingFrame object.
45  //
46
47  public static boolean checkSecurity() {
48    SecurityManager security = System.getSecurityManager();
49    if (security != null) {
50      try {
51        security.checkPropertyAccess("user.dir");
52        security.checkPropertyAccess("file.separator");
53        // Work around (rare) checkPropertyAccess bug
54        System.getProperty("user.dir");
55      } catch (SecurityException e) {
56        System.out.println("SecurityManager restricts session recording.");
57        return false;
58      }
59    }
60    return true;
61  }
62
63  //
64  // Constructor.
65  //
66
67  RecordingFrame(VncViewer v) {
68    super("TightVNC Session Recording");
69
70    viewer = v;
71
72    // Determine initial filename for next saved session.
73    // FIXME: Check SecurityManager.
74
75    String fname = nextNewFilename(System.getProperty("user.dir") +
76                                   System.getProperty("file.separator") +
77                                   "vncsession.fbs");
78
79    // Construct new panel with file name field and "Browse" button.
80
81    Panel fnamePanel = new Panel();
82    GridBagLayout fnameGridbag = new GridBagLayout();
83    fnamePanel.setLayout(fnameGridbag);
84
85    GridBagConstraints fnameConstraints = new GridBagConstraints();
86    fnameConstraints.gridwidth = GridBagConstraints.RELATIVE;
87    fnameConstraints.fill = GridBagConstraints.BOTH;
88    fnameConstraints.weightx = 4.0;
89
90    fnameField = new TextField(fname, 64);
91    fnameGridbag.setConstraints(fnameField, fnameConstraints);
92    fnamePanel.add(fnameField);
93    fnameField.addActionListener(this);
94
95    fnameConstraints.gridwidth = GridBagConstraints.REMAINDER;
96    fnameConstraints.weightx = 1.0;
97
98    browseButton = new Button("Browse");
99    fnameGridbag.setConstraints(browseButton, fnameConstraints);
100    fnamePanel.add(browseButton);
101    browseButton.addActionListener(this);
102
103    // Construct the frame.
104
105    GridBagLayout gridbag = new GridBagLayout();
106    setLayout(gridbag);
107
108    GridBagConstraints gbc = new GridBagConstraints();
109    gbc.gridwidth = GridBagConstraints.REMAINDER;
110    gbc.fill = GridBagConstraints.BOTH;
111    gbc.weighty = 1.0;
112    gbc.insets = new Insets(10, 0, 0, 0);
113
114    Label helpLabel =
115      new Label("File name to save next recorded session in:", Label.CENTER);
116    gridbag.setConstraints(helpLabel, gbc);
117    add(helpLabel);
118
119    gbc.fill = GridBagConstraints.HORIZONTAL;
120    gbc.weighty = 0.0;
121    gbc.insets = new Insets(0, 0, 0, 0);
122
123    gridbag.setConstraints(fnamePanel, gbc);
124    add(fnamePanel);
125
126    gbc.fill = GridBagConstraints.BOTH;
127    gbc.weighty = 1.0;
128    gbc.insets = new Insets(10, 0, 10, 0);
129
130    statusLabel = new Label("", Label.CENTER);
131    gridbag.setConstraints(statusLabel, gbc);
132    add(statusLabel);
133
134    gbc.fill = GridBagConstraints.HORIZONTAL;
135    gbc.weightx = 1.0;
136    gbc.weighty = 0.0;
137    gbc.gridwidth = 1;
138    gbc.insets = new Insets(0, 0, 0, 0);
139
140    recordButton = new Button("Record");
141    gridbag.setConstraints(recordButton, gbc);
142    add(recordButton);
143    recordButton.addActionListener(this);
144
145    nextButton = new Button("Next file");
146    gridbag.setConstraints(nextButton, gbc);
147    add(nextButton);
148    nextButton.addActionListener(this);
149
150    closeButton = new Button("Close");
151    gridbag.setConstraints(closeButton, gbc);
152    add(closeButton);
153    closeButton.addActionListener(this);
154
155    // Set correct text, font and color for the statusLabel.
156    stopRecording();
157
158    pack();
159
160    addWindowListener(this);
161  }
162
163  //
164  // If the given string ends with ".NNN" where NNN is a decimal
165  // number, increase this number by one. Otherwise, append ".001"
166  // to the given string.
167  //
168
169  protected String nextFilename(String fname) {
170    int len = fname.length();
171    int suffixPos = len;
172    int suffixNum = 1;
173
174    if (len > 4 && fname.charAt(len - 4) == '.') {
175      try {
176        suffixNum = Integer.parseInt(fname.substring(len - 3, len)) + 1;
177        suffixPos = len - 4;
178      } catch (NumberFormatException e) { }
179    }
180
181    char[] zeroes = {'0', '0', '0'};
182    String suffix = String.valueOf(suffixNum);
183    if (suffix.length() < 3) {
184      suffix = new String(zeroes, 0, 3 - suffix.length()) + suffix;
185    }
186
187    return fname.substring(0, suffixPos) + '.' + suffix;
188  }
189
190  //
191  // Find next name of a file which does not exist yet.
192  //
193
194  protected String nextNewFilename(String fname) {
195    String newName = fname;
196    File f;
197    try {
198      do {
199        newName = nextFilename(newName);
200        f = new File(newName);
201      } while (f.exists());
202    } catch (SecurityException e) { }
203
204    return newName;
205  }
206
207  //
208  // Let the user choose a file name showing a FileDialog.
209  //
210
211  protected boolean browseFile() {
212    File currentFile = new File(fnameField.getText());
213
214    FileDialog fd =
215      new FileDialog(this, "Save next session as...", FileDialog.SAVE);
216    fd.setDirectory(currentFile.getParent());
217    fd.setVisible(true);
218    if (fd.getFile() != null) {
219      String newDir = fd.getDirectory();
220      String sep = System.getProperty("file.separator");
221      if (newDir.length() > 0) {
222        if (!sep.equals(newDir.substring(newDir.length() - sep.length())))
223          newDir += sep;
224      }
225      String newFname = newDir + fd.getFile();
226      if (newFname.equals(fnameField.getText())) {
227        fnameField.setText(newFname);
228        return true;
229      }
230    }
231    return false;
232  }
233
234  //
235  // Start recording.
236  //
237
238  public void startRecording() {
239    statusLabel.setText("Status: Recording...");
240    statusLabel.setFont(new Font("Helvetica", Font.BOLD, 12));
241    statusLabel.setForeground(Color.red);
242    recordButton.setLabel("Stop recording");
243
244    recording = true;
245
246    viewer.setRecordingStatus(fnameField.getText());
247  }
248
249  //
250  // Stop recording.
251  //
252
253  public void stopRecording() {
254    statusLabel.setText("Status: Not recording.");
255    statusLabel.setFont(new Font("Helvetica", Font.PLAIN, 12));
256    statusLabel.setForeground(Color.black);
257    recordButton.setLabel("Record");
258
259    recording = false;
260
261    viewer.setRecordingStatus(null);
262  }
263
264  //
265  // Close our window properly.
266  //
267
268  public void windowClosing(WindowEvent evt) {
269    setVisible(false);
270  }
271
272  //
273  // Ignore window events we're not interested in.
274  //
275
276  public void windowActivated(WindowEvent evt) {}
277  public void windowDeactivated (WindowEvent evt) {}
278  public void windowOpened(WindowEvent evt) {}
279  public void windowClosed(WindowEvent evt) {}
280  public void windowIconified(WindowEvent evt) {}
281  public void windowDeiconified(WindowEvent evt) {}
282
283
284  //
285  // Respond to button presses
286  //
287
288  public void actionPerformed(ActionEvent evt) {
289    if (evt.getSource() == browseButton) {
290      if (browseFile() && recording)
291        startRecording();
292
293    } else if (evt.getSource() == recordButton) {
294      if (!recording) {
295        startRecording();
296      } else {
297        stopRecording();
298        fnameField.setText(nextNewFilename(fnameField.getText()));
299      }
300
301    } else if (evt.getSource() == nextButton) {
302      fnameField.setText(nextNewFilename(fnameField.getText()));
303      if (recording)
304        startRecording();
305
306    } else if (evt.getSource() == closeButton) {
307      setVisible(false);
308
309    }
310  }
311}
Note: See TracBrowser for help on using the repository browser.