1 package com.nexuiz.demorecorder.ui.swinggui;
\r
3 import java.awt.Container;
\r
4 import java.awt.Dimension;
\r
5 import java.awt.Point;
\r
6 import java.awt.event.ActionEvent;
\r
7 import java.awt.event.ActionListener;
\r
8 import java.awt.event.MouseEvent;
\r
9 import java.awt.event.MouseListener;
\r
10 import java.awt.event.WindowEvent;
\r
11 import java.awt.event.WindowListener;
\r
12 import java.io.File;
\r
13 import java.io.FileInputStream;
\r
14 import java.io.FileOutputStream;
\r
15 import java.io.IOException;
\r
16 import java.io.InputStream;
\r
17 import java.io.ObjectInputStream;
\r
18 import java.io.ObjectOutputStream;
\r
19 import java.net.URL;
\r
20 import java.util.ArrayList;
\r
21 import java.util.List;
\r
23 import javax.help.HelpBroker;
\r
24 import javax.help.HelpSet;
\r
25 import javax.swing.BorderFactory;
\r
26 import javax.swing.Icon;
\r
27 import javax.swing.ImageIcon;
\r
28 import javax.swing.JButton;
\r
29 import javax.swing.JFileChooser;
\r
30 import javax.swing.JFrame;
\r
31 import javax.swing.JMenu;
\r
32 import javax.swing.JMenuBar;
\r
33 import javax.swing.JMenuItem;
\r
34 import javax.swing.JOptionPane;
\r
35 import javax.swing.JPanel;
\r
36 import javax.swing.JPopupMenu;
\r
37 import javax.swing.JScrollPane;
\r
38 import javax.swing.JTable;
\r
39 import javax.swing.UIManager;
\r
40 import javax.swing.border.TitledBorder;
\r
42 import net.miginfocom.swing.MigLayout;
\r
44 import org.jdesktop.swingx.JXTable;
\r
46 import com.nexuiz.demorecorder.application.DemoRecorderApplication;
\r
47 import com.nexuiz.demorecorder.application.DemoRecorderUtils;
\r
48 import com.nexuiz.demorecorder.application.NDRPreferences;
\r
49 import com.nexuiz.demorecorder.application.DemoRecorderApplication.Preferences;
\r
50 import com.nexuiz.demorecorder.application.jobs.RecordJob;
\r
51 import com.nexuiz.demorecorder.application.jobs.RecordJob.State;
\r
52 import com.nexuiz.demorecorder.application.plugins.EncoderPlugin;
\r
53 import com.nexuiz.demorecorder.ui.DemoRecorderUI;
\r
54 import com.nexuiz.demorecorder.ui.swinggui.tablemodels.RecordJobTemplatesTableModel;
\r
55 import com.nexuiz.demorecorder.ui.swinggui.tablemodels.RecordJobsTableModel;
\r
56 import com.nexuiz.demorecorder.ui.swinggui.utils.ShowErrorDialogExceptionHandler;
\r
57 import com.nexuiz.demorecorder.ui.swinggui.utils.XProperties;
\r
58 import com.nexuiz.demorecorder.ui.swinggui.utils.XProperties.XTableState;
\r
60 public class SwingGUI extends JFrame implements WindowListener, DemoRecorderUI {
\r
62 private static final long serialVersionUID = -7287303462488231068L;
\r
63 public static final String JOB_TABLE_PREFERENCES_FILENAME = "jobsTable.pref";
\r
64 public static final String TEMPLATE_TABLE_PREFERENCES_FILENAME = "templatesTable.pref";
\r
65 public static final String TEMPLATE_TABLE_CONTENT_FILENAME = "templates.dat";
\r
67 private DemoRecorderApplication appLayer;
\r
68 private PreferencesDialog preferencesDialog;
\r
70 private JXTable jobsTable = null;
\r
71 private JPopupMenu jobsTablePopupMenu;
\r
72 private ActionListener jobButtonActionListener = new JobButtonActionListener();
\r
73 private MouseListener jobsTableMouseListener = new JobsTableMouseListener();
\r
75 private JXTable templatesTable = null;
\r
76 private JPopupMenu templatesTablePopupMenu;
\r
77 private ActionListener templateButtonActionListener = new TemplateButtonActionListener();
\r
78 private MouseListener templatesTableMouseListener = new TemplatesTableMouseListener();
\r
80 private ActionListener recordButtonActionListener = new RecordButtonActionListener();
\r
82 private static final String LABEL_JOB_CREATE = "Create";
\r
83 private static final String LABEL_JOB_CREATE_FROM_TEMPL = "Create from template";
\r
84 private static final String LABEL_JOB_DELETE = "Delete";
\r
85 private static final String LABEL_JOB_CLEAR = "Clear";
\r
86 private static final String LABEL_JOB_EDIT = "Edit job";
\r
87 private static final String LABEL_JOB_DUPLICATE = "Duplicate job";
\r
88 private static final String LABEL_JOB_APPLYTEMPL = "Apply template";
\r
89 private static final String LABEL_JOB_START = "Start job";
\r
90 private static final String LABEL_JOB_SHOWERROR = "Show error message";
\r
91 private static final String LABEL_JOB_RESET_STATE_WAITING = "Reset job status to 'waiting'";
\r
92 private static final String LABEL_JOB_RESET_STATE_DONE = "Reset job status to 'done'";
\r
94 private static final String LABEL_TEMPL_CREATE = "Create";
\r
95 private static final String LABEL_TEMPL_CREATE_FROM_JOB = "Create from job";
\r
96 private static final String LABEL_TEMPL_DELETE = "Delete";
\r
97 private static final String LABEL_TEMPL_CLEAR = "Clear";
\r
98 private static final String LABEL_TEMPL_EDIT = "Edit template";
\r
99 private static final String LABEL_TEMPL_DUPLICATE = "Duplicate template";
\r
101 private ActionListener menuButtonActionListener = new MenuButtonActionListener();
\r
102 private JMenuItem fileLoadQueue = new JMenuItem("Load job queue", getIcon("fileopen.png"));
\r
103 private JMenuItem fileSaveQueue = new JMenuItem("Save job queue", getIcon("filesave.png"));
\r
104 private JMenuItem fileLoadTemplates = new JMenuItem("Load templates", getIcon("fileopen.png"));
\r
105 private JMenuItem fileSaveTemplates = new JMenuItem("Save templates", getIcon("filesave.png"));
\r
106 private JMenuItem filePreferences = new JMenuItem("Preferences", getIcon("advanced.png"));
\r
107 private JMenuItem fileExit = new JMenuItem("Exit", getIcon("exit.png"));
\r
108 private JMenuItem helpHelp = new JMenuItem("Show help", getIcon("help.png"));
\r
109 private JMenuItem helpAbout = new JMenuItem("About", getIcon("info.png"));
\r
110 private JFileChooser jobQueueSaveAsFC = new JFileChooser();
\r
111 private JFileChooser templatesSaveAsFC = new JFileChooser();
\r
113 private JButton jobs_create = new JButton(LABEL_JOB_CREATE, getIcon("edit_add.png"));
\r
114 private JButton jobs_createFromTempl = new JButton(LABEL_JOB_CREATE_FROM_TEMPL, getIcon("view_right_p.png"));
\r
115 private JButton jobs_delete = new JButton(LABEL_JOB_DELETE, getIcon("editdelete.png"));
\r
116 private JButton jobs_clear = new JButton(LABEL_JOB_CLEAR, getIcon("editclear.png"));
\r
117 private JMenuItem jobs_contextmenu_edit = new JMenuItem(LABEL_JOB_EDIT, getIcon("edit.png"));
\r
118 private JMenuItem jobs_contextmenu_duplicate = new JMenuItem(LABEL_JOB_DUPLICATE, getIcon("editcopy.png"));
\r
119 private JMenuItem jobs_contextmenu_applytempl = new JMenuItem(LABEL_JOB_APPLYTEMPL, getIcon("editpaste.png"));
\r
120 private JMenuItem jobs_contextmenu_delete = new JMenuItem(LABEL_JOB_DELETE, getIcon("editdelete.png"));
\r
121 private JMenuItem jobs_contextmenu_start = new JMenuItem(LABEL_JOB_START, getIcon("player_play.png"));
\r
122 private JMenuItem jobs_contextmenu_showerror = new JMenuItem(LABEL_JOB_SHOWERROR, getIcon("status_unknown.png"));
\r
123 private JMenuItem jobs_contextmenu_resetstate_waiting = new JMenuItem(LABEL_JOB_RESET_STATE_WAITING, getIcon("quick_restart.png"));
\r
124 private JMenuItem jobs_contextmenu_resetstate_done = new JMenuItem(LABEL_JOB_RESET_STATE_DONE, getIcon("quick_restart_blue.png"));
\r
125 private List<JMenuItem> jobs_contextmenu_runPluginMenuItems = new ArrayList<JMenuItem>();
\r
127 private JButton templ_create = new JButton(LABEL_TEMPL_CREATE, getIcon("edit_add.png"));
\r
128 private JButton templ_createFromJob = new JButton(LABEL_TEMPL_CREATE_FROM_JOB, getIcon("view_right_p.png"));
\r
129 private JButton templ_delete = new JButton(LABEL_TEMPL_DELETE, getIcon("editdelete.png"));
\r
130 private JButton templ_clear = new JButton(LABEL_TEMPL_CLEAR, getIcon("editclear.png"));
\r
131 private JMenuItem templ_contextmenu_edit = new JMenuItem(LABEL_TEMPL_EDIT, getIcon("edit.png"));
\r
132 private JMenuItem templ_contextmenu_duplicate = new JMenuItem(LABEL_TEMPL_DUPLICATE, getIcon("editcopy.png"));
\r
133 private JMenuItem templ_contextmenu_delete = new JMenuItem(LABEL_TEMPL_DELETE, getIcon("editdelete.png"));
\r
135 private static final String PROCESSING_START = "Start processing";
\r
136 private static final String PROCESSING_STOP_NOW = "Stop processing";
\r
137 private static final String PROCESSING_STOP_LATER = "Processing will stop after current job finished";
\r
138 private JButton processing_start = new JButton(PROCESSING_START, getIcon("player_play.png"));
\r
139 private JButton processing_stop = new JButton(PROCESSING_STOP_NOW, getIcon("player_pause.png"));
\r
141 private StatusBar statusBar = new StatusBar();
\r
143 private static HelpBroker mainHelpBroker = null;
\r
144 private static final String mainHelpSetName = "help/DemoRecorderHelp.hs";
\r
146 public SwingGUI(DemoRecorderApplication appLayer) {
\r
147 super("Nexuiz Demo Recorder v0.3");
\r
148 addWindowListener(this);
\r
150 this.appLayer = appLayer;
\r
152 this.setupLayout();
\r
154 this.preferencesDialog = new PreferencesDialog(this, appLayer);
\r
156 setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
\r
157 // Display the window.
\r
160 //now that we have the GUI we can set the parent window for the error dialog
\r
161 ShowErrorDialogExceptionHandler.setParentWindow(this);
\r
164 private void setupHelp() {
\r
165 if (mainHelpBroker == null){
\r
166 HelpSet mainHelpSet = null;
\r
169 URL hsURL = HelpSet.findHelpSet(null, mainHelpSetName);
\r
170 mainHelpSet = new HelpSet(null, hsURL);
\r
171 } catch (Exception e) {
\r
172 DemoRecorderUtils.showNonCriticalErrorDialog("Could not properly create the help", e, true);
\r
175 if (mainHelpSet != null)
\r
176 mainHelpBroker = mainHelpSet.createHelpBroker();
\r
180 private void setupLayout() {
\r
181 setLayout(new MigLayout("wrap 1,insets 10", "[400:700:,grow,fill]",
\r
182 "[grow,fill][grow,fill][][]"));
\r
183 Container contentPane = getContentPane();
\r
184 setJMenuBar(this.buildMenu());
\r
186 this.setupTemplatePanel();
\r
187 this.setupJobPanel();
\r
188 this.setupRecordPanel();
\r
190 contentPane.add(statusBar, "south,height 23::");
\r
193 private void setupTemplatePanel() {
\r
194 JPanel templatePanel = new JPanel(new MigLayout("", "[500:500:,grow,fill][170!,fill,grow]", "[grow,fill]"));
\r
195 TitledBorder templatePanelTitle = BorderFactory.createTitledBorder("Templates");
\r
196 templatePanel.setBorder(templatePanelTitle);
\r
197 getContentPane().add(templatePanel);
\r
199 this.setupTemplatesTable();
\r
200 this.loadTableStates(this.templatesTable);
\r
201 JScrollPane templateScrollPane = new JScrollPane(templatesTable);
\r
202 templatePanel.add(templateScrollPane);
\r
204 this.templ_create.addActionListener(this.templateButtonActionListener);
\r
205 this.templ_createFromJob.addActionListener(this.templateButtonActionListener);
\r
206 this.templ_delete.addActionListener(this.templateButtonActionListener);
\r
207 this.templ_clear.addActionListener(this.templateButtonActionListener);
\r
209 this.templ_contextmenu_edit.addActionListener(this.templateButtonActionListener);
\r
210 this.templ_contextmenu_duplicate.addActionListener(this.templateButtonActionListener);
\r
211 this.templ_contextmenu_delete.addActionListener(this.templateButtonActionListener);
\r
213 this.configureTableButtons();
\r
215 JPanel templateControlButtonPanel = new JPanel(new MigLayout("wrap 1", "fill,grow"));
\r
216 templateControlButtonPanel.add(this.templ_create);
\r
217 templateControlButtonPanel.add(this.templ_createFromJob);
\r
218 templateControlButtonPanel.add(this.templ_delete);
\r
219 templateControlButtonPanel.add(this.templ_clear);
\r
220 templatePanel.add(templateControlButtonPanel);
\r
223 private void setupJobPanel() {
\r
224 JPanel jobPanel = new JPanel(new MigLayout("", "[500:500:,grow,fill][170!,fill,grow]", "[grow,fill]"));
\r
225 TitledBorder jobPanelTitle = BorderFactory.createTitledBorder("Jobs");
\r
226 jobPanel.setBorder(jobPanelTitle);
\r
227 getContentPane().add(jobPanel);
\r
229 this.setupJobsTable();
\r
230 this.loadTableStates(this.jobsTable);
\r
232 JScrollPane jobScrollPane = new JScrollPane(jobsTable);
\r
233 jobPanel.add(jobScrollPane);
\r
235 this.jobs_create.addActionListener(this.jobButtonActionListener);
\r
236 this.jobs_createFromTempl.addActionListener(this.jobButtonActionListener);
\r
237 this.jobs_delete.addActionListener(this.jobButtonActionListener);
\r
238 this.jobs_clear.addActionListener(this.jobButtonActionListener);
\r
240 this.jobs_contextmenu_edit.addActionListener(this.jobButtonActionListener);
\r
241 this.jobs_contextmenu_duplicate.addActionListener(this.jobButtonActionListener);
\r
242 this.jobs_contextmenu_applytempl.addActionListener(this.jobButtonActionListener);
\r
243 this.jobs_contextmenu_delete.addActionListener(this.jobButtonActionListener);
\r
244 this.jobs_contextmenu_start.addActionListener(this.jobButtonActionListener);
\r
245 this.jobs_contextmenu_showerror.addActionListener(this.jobButtonActionListener);
\r
246 this.jobs_contextmenu_resetstate_waiting.addActionListener(this.jobButtonActionListener);
\r
247 this.jobs_contextmenu_resetstate_done.addActionListener(this.jobButtonActionListener);
\r
249 //initialize button states
\r
250 configureTableButtons();
\r
252 JPanel jobControlButtonPanel = new JPanel(new MigLayout("wrap 1", "fill,grow"));
\r
253 jobControlButtonPanel.add(this.jobs_create);
\r
254 jobControlButtonPanel.add(this.jobs_createFromTempl);
\r
255 jobControlButtonPanel.add(this.jobs_delete);
\r
256 jobControlButtonPanel.add(this.jobs_clear);
\r
257 jobPanel.add(jobControlButtonPanel);
\r
260 private void setupJobsTable() {
\r
261 RecordJobsTableModel tableModel = new RecordJobsTableModel(this.appLayer);
\r
262 jobsTable = new JXTable(tableModel);
\r
263 jobsTable.setColumnControlVisible(true);
\r
264 jobsTable.setPreferredScrollableViewportSize(new Dimension(400, 100));
\r
265 jobsTable.addMouseListener(this.jobsTableMouseListener);
\r
268 private void setupTemplatesTable() {
\r
269 RecordJobTemplatesTableModel tableModel = new RecordJobTemplatesTableModel();
\r
270 templatesTable = new JXTable(tableModel);
\r
271 templatesTable.setColumnControlVisible(true);
\r
272 templatesTable.setPreferredScrollableViewportSize(new Dimension(400, 100));
\r
273 templatesTable.addMouseListener(this.templatesTableMouseListener);
\r
276 private void setupRecordPanel() {
\r
277 JPanel recButtonPanel = new JPanel(new MigLayout());
\r
278 recButtonPanel.add(processing_start);
\r
279 recButtonPanel.add(processing_stop);
\r
280 processing_stop.setEnabled(false);
\r
281 processing_start.addActionListener(recordButtonActionListener);
\r
282 processing_stop.addActionListener(recordButtonActionListener);
\r
283 getContentPane().add(recButtonPanel);
\r
286 public static void setSystemLAF() {
\r
289 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
\r
290 } catch (Exception e) {
\r
294 public void RecordJobPropertiesChange(RecordJob job) {
\r
295 RecordJobsTableModel jobsTableModel = (RecordJobsTableModel) this.jobsTable.getModel();
\r
296 List<RecordJob> recordJobs = jobsTableModel.getRecordJobs();
\r
297 int jobIndex = recordJobs.indexOf(job);
\r
298 if (jobIndex == -1) {
\r
300 recordJobs.add(job);
\r
301 //add job at the end of the table:
\r
302 int position = jobsTableModel.getRowCount() - 1;
\r
303 jobsTableModel.fireTableRowsInserted(position, position);
\r
305 //job already existed
\r
306 jobIndex = this.jobsTable.convertRowIndexToView(jobIndex); //convert due to possible view sorting
\r
307 jobsTableModel.fireTableRowsUpdated(jobIndex, jobIndex);
\r
311 public void recordingFinished() {
\r
312 JOptionPane.showMessageDialog(SwingGUI.this, "Finished recording all jobs", "Recording done", JOptionPane.INFORMATION_MESSAGE);
\r
313 statusBar.showState(false);
\r
314 processing_start.setEnabled(true);
\r
315 processing_stop.setEnabled(false);
\r
316 processing_stop.setText(PROCESSING_STOP_NOW);
\r
319 private JMenuBar buildMenu() {
\r
320 JMenuBar menuBar = new JMenuBar();
\r
322 JMenu fileMenu = new JMenu("File");
\r
323 fileMenu.add(fileLoadQueue);
\r
324 fileMenu.add(fileSaveQueue);
\r
325 fileMenu.add(fileLoadTemplates);
\r
326 fileMenu.add(fileSaveTemplates);
\r
327 fileMenu.add(filePreferences);
\r
328 fileMenu.add(fileExit);
\r
329 menuBar.add(fileMenu);
\r
331 fileLoadQueue.addActionListener(menuButtonActionListener);
\r
332 fileSaveQueue.addActionListener(menuButtonActionListener);
\r
333 fileLoadTemplates.addActionListener(menuButtonActionListener);
\r
334 fileSaveTemplates.addActionListener(menuButtonActionListener);
\r
335 filePreferences.addActionListener(menuButtonActionListener);
\r
336 fileExit.addActionListener(menuButtonActionListener);
\r
338 JMenu helpMenu = new JMenu("Help");
\r
339 helpMenu.add(helpHelp);
\r
340 helpMenu.add(helpAbout);
\r
341 menuBar.add(helpMenu);
\r
343 helpHelp.addActionListener(menuButtonActionListener);
\r
344 helpAbout.addActionListener(menuButtonActionListener);
\r
346 this.setupEncoderPluginButtons();
\r
348 this.jobsTablePopupMenu = new JPopupMenu();
\r
349 this.jobsTablePopupMenu.add(jobs_contextmenu_edit);
\r
350 this.jobsTablePopupMenu.add(jobs_contextmenu_duplicate);
\r
351 this.jobsTablePopupMenu.add(jobs_contextmenu_applytempl);
\r
352 this.jobsTablePopupMenu.add(jobs_contextmenu_delete);
\r
353 this.jobsTablePopupMenu.add(jobs_contextmenu_start);
\r
354 //add JMenus for plugins
\r
355 for (JMenuItem menuItem : jobs_contextmenu_runPluginMenuItems) {
\r
356 this.jobsTablePopupMenu.add(menuItem);
\r
358 this.jobsTablePopupMenu.add(jobs_contextmenu_showerror);
\r
359 this.jobsTablePopupMenu.add(jobs_contextmenu_resetstate_waiting);
\r
360 this.jobsTablePopupMenu.add(jobs_contextmenu_resetstate_done);
\r
365 this.templatesTablePopupMenu = new JPopupMenu();
\r
366 this.templatesTablePopupMenu.add(templ_contextmenu_edit);
\r
367 this.templatesTablePopupMenu.add(templ_contextmenu_duplicate);
\r
368 this.templatesTablePopupMenu.add(templ_contextmenu_delete);
\r
373 private void setupEncoderPluginButtons() {
\r
374 for (EncoderPlugin plugin : appLayer.getEncoderPlugins()) {
\r
375 JMenuItem pluginMenuItem = new JMenuItem("Just run " + plugin.getName() + " plugin", getIcon("package.png"));
\r
376 pluginMenuItem.addActionListener(jobButtonActionListener);
\r
377 this.jobs_contextmenu_runPluginMenuItems.add(pluginMenuItem);
\r
381 private void saveTableStates(JXTable table) {
\r
383 if (table == jobsTable) {
\r
384 fileName = JOB_TABLE_PREFERENCES_FILENAME;
\r
386 fileName = TEMPLATE_TABLE_PREFERENCES_FILENAME;
\r
388 String exceptionMessage = "An error occurred while trying to save the table state file " + fileName;
\r
390 XProperties.XTableProperty t = new XProperties.XTableProperty();
\r
391 XTableState tableState;
\r
393 tableState = (XTableState) t.getSessionState(table);
\r
394 } catch (Exception e) { //most likely ClassCastException
\r
395 DemoRecorderUtils.showNonCriticalErrorDialog(exceptionMessage, e, true);
\r
399 File tableStateFile = DemoRecorderUtils.computeLocalFile(DemoRecorderApplication.PREFERENCES_DIRNAME, fileName);
\r
400 DemoRecorderUtils.attemptFileCreation(tableStateFile);
\r
403 FileOutputStream fout = new FileOutputStream(tableStateFile);
\r
404 ObjectOutputStream oos = new ObjectOutputStream(fout);
\r
405 oos.writeObject(tableState);
\r
407 } catch (Exception e) {
\r
408 DemoRecorderUtils.showNonCriticalErrorDialog(exceptionMessage, e, true);
\r
412 private void loadTableStates(JXTable table) {
\r
414 if (table == jobsTable) {
\r
415 fileName = JOB_TABLE_PREFERENCES_FILENAME;
\r
417 fileName = TEMPLATE_TABLE_PREFERENCES_FILENAME;
\r
420 XProperties.XTableProperty t = new XProperties.XTableProperty();
\r
422 File tableStateFile = DemoRecorderUtils.computeLocalFile(DemoRecorderApplication.PREFERENCES_DIRNAME, fileName);
\r
424 XTableState tableState;
\r
427 FileInputStream fin = new FileInputStream(tableStateFile);
\r
428 ObjectInputStream ois = new ObjectInputStream(fin);
\r
429 tableState = (XTableState) ois.readObject();
\r
430 t.setSessionState(table, tableState);
\r
431 } catch (Exception e) {
\r
432 //manually hide columns
\r
433 if (table == jobsTable) {
\r
434 //re-create table to be sure
\r
435 this.setupJobsTable();
\r
436 //manually hide some columns
\r
437 jobsTable.getColumnExt(RecordJobsTableModel.EXECUTE_AFTER_CAP).setVisible(false);
\r
438 jobsTable.getColumnExt(RecordJobsTableModel.EXECUTE_BEFORE_CAP).setVisible(false);
\r
439 jobsTable.getColumnExt(RecordJobsTableModel.VIDEO_DESTINATION_PATH).setVisible(false);
\r
440 jobsTable.getColumnExt(RecordJobsTableModel.DPVIDEO_PATH).setVisible(false);
\r
441 jobsTable.getColumnExt(RecordJobsTableModel.RELATIVE_DEMO_PATH).setVisible(false);
\r
442 jobsTable.getColumnExt(RecordJobsTableModel.ENGINE_PARAMETERS).setVisible(false);
\r
443 jobsTable.getColumnExt(RecordJobsTableModel.ENGINE_PATH).setVisible(false);
\r
445 //re-create table to be sure
\r
446 this.setupTemplatesTable();
\r
447 //manually hide some columns
\r
448 templatesTable.getColumnExt(RecordJobTemplatesTableModel.EXECUTE_AFTER_CAP).setVisible(false);
\r
449 templatesTable.getColumnExt(RecordJobTemplatesTableModel.EXECUTE_BEFORE_CAP).setVisible(false);
\r
450 templatesTable.getColumnExt(RecordJobTemplatesTableModel.VIDEO_DESTINATION_PATH).setVisible(false);
\r
451 templatesTable.getColumnExt(RecordJobTemplatesTableModel.DPVIDEO_PATH).setVisible(false);
\r
452 templatesTable.getColumnExt(RecordJobTemplatesTableModel.RELATIVE_DEMO_PATH).setVisible(false);
\r
453 templatesTable.getColumnExt(RecordJobTemplatesTableModel.DEMO_FILE_PATH).setVisible(false);
\r
454 templatesTable.getColumnExt(RecordJobTemplatesTableModel.ENGINE_PARAMETERS).setVisible(false);
\r
455 templatesTable.getColumnExt(RecordJobTemplatesTableModel.ENGINE_PATH).setVisible(false);
\r
456 templatesTable.getColumnExt(RecordJobTemplatesTableModel.JOB_NAME).setVisible(false);
\r
461 private class MenuButtonActionListener implements ActionListener {
\r
463 public void actionPerformed(ActionEvent e) {
\r
464 if (e.getSource() == fileLoadQueue) {
\r
465 int result = jobQueueSaveAsFC.showOpenDialog(SwingGUI.this);
\r
466 if (result == JFileChooser.APPROVE_OPTION) {
\r
467 File selectedFile = jobQueueSaveAsFC.getSelectedFile();
\r
468 if (selectedFile.isFile()) {
\r
469 RecordJobsTableModel tableModel = (RecordJobsTableModel) jobsTable.getModel();
\r
470 tableModel.loadNewJobQueue(SwingGUI.this, selectedFile, jobsTable);
\r
471 configureTableButtons();
\r
475 } else if (e.getSource() == fileSaveQueue) {
\r
476 int result = jobQueueSaveAsFC.showSaveDialog(SwingGUI.this);
\r
477 if (result == JFileChooser.APPROVE_OPTION) {
\r
478 File selectedFile = jobQueueSaveAsFC.getSelectedFile();
\r
479 if (!DemoRecorderUtils.getFileExtension(selectedFile).equals("queue")) {
\r
480 //if file is not a .queue file, make it one
\r
481 selectedFile = new File(selectedFile.getAbsoluteFile() + ".queue");
\r
483 if (selectedFile.exists()) {
\r
484 int confirm = JOptionPane.showConfirmDialog(SwingGUI.this, "File already exists. Are you sure you want to overwrite it?", "Confirm overwrite", JOptionPane.YES_NO_OPTION);
\r
485 if (confirm == JOptionPane.NO_OPTION) {
\r
489 appLayer.saveJobQueue(selectedFile);
\r
491 } else if (e.getSource() == fileLoadTemplates) {
\r
492 int result = templatesSaveAsFC.showOpenDialog(SwingGUI.this);
\r
493 if (result == JFileChooser.APPROVE_OPTION) {
\r
494 File selectedFile = templatesSaveAsFC.getSelectedFile();
\r
495 if (selectedFile.isFile()) {
\r
496 RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();
\r
497 tableModel.loadNewTemplateList(SwingGUI.this, selectedFile, templatesTable);
\r
498 configureTableButtons();
\r
501 } else if (e.getSource() == fileSaveTemplates) {
\r
502 int result = templatesSaveAsFC.showSaveDialog(SwingGUI.this);
\r
503 if (result == JFileChooser.APPROVE_OPTION) {
\r
504 File selectedFile = templatesSaveAsFC.getSelectedFile();
\r
505 if (!DemoRecorderUtils.getFileExtension(selectedFile).equals("templ")) {
\r
506 selectedFile = new File(selectedFile.getAbsoluteFile() + ".templ");
\r
508 if (selectedFile.exists()) {
\r
509 int confirm = JOptionPane.showConfirmDialog(SwingGUI.this, "File already exists. Are you sure you want to overwrite it?", "Confirm overwrite", JOptionPane.YES_NO_OPTION);
\r
510 if (confirm == JOptionPane.NO_OPTION) {
\r
514 RecordJobTemplatesTableModel model = (RecordJobTemplatesTableModel) templatesTable.getModel();
\r
515 model.saveTemplateListToFile(selectedFile);
\r
517 } else if (e.getSource() == filePreferences) {
\r
518 preferencesDialog.showDialog();
\r
519 } else if (e.getSource() == fileExit) {
\r
521 } else if (e.getSource() == helpHelp) {
\r
522 if (mainHelpBroker != null) {
\r
523 mainHelpBroker.setDisplayed(true);
\r
525 } else if (e.getSource() == helpAbout) {
\r
533 * Listens to the clicks on buttons that are in the job panel (next to the jobs table)
\r
534 * or its context menu.
\r
536 private class JobButtonActionListener implements ActionListener {
\r
538 public void actionPerformed(ActionEvent e) {
\r
539 List<RecordJob> selectedJobs = getSelectedRecordJobs(jobsTable);
\r
540 List<RecordJob> selectedTemplates = getSelectedRecordJobs(templatesTable);
\r
541 if (e.getSource() == jobs_create) {
\r
542 JobDialog jobDialog = new JobDialog(SwingGUI.this, appLayer);
\r
543 jobDialog.showDialog();
\r
544 configureTableButtons();
\r
546 else if (e.getSource() == jobs_createFromTempl) {
\r
547 if (selectedTemplates.size() != 1) {
\r
550 RecordJobTemplate template = (RecordJobTemplate) selectedTemplates.get(0);
\r
551 // JobDialog jobDialog = new JobDialog(SwingGUI.this, template, appLayer);
\r
552 JobDialog jobDialog = new JobDialog(SwingGUI.this, template, appLayer, JobDialog.CREATE_JOB_FROM_TEMPLATE);
\r
553 jobDialog.showDialog();
\r
554 configureTableButtons();
\r
556 else if (e.getSource() == jobs_delete || e.getSource() == jobs_contextmenu_delete) {
\r
557 int result = JOptionPane.showConfirmDialog(SwingGUI.this, "Are you sure you want to delete the selected job(s)?", "Confirm delete", JOptionPane.YES_NO_OPTION);
\r
558 if (result == JOptionPane.YES_OPTION) {
\r
559 deleteSelectedJobs(false);
\r
560 configureTableButtons();
\r
563 else if (e.getSource() == jobs_clear) {
\r
564 int result = JOptionPane.showConfirmDialog(SwingGUI.this, "Are you sure you want to clear the job list?", "Confirm clear", JOptionPane.YES_NO_OPTION);
\r
565 if (result == JOptionPane.YES_OPTION) {
\r
566 deleteSelectedJobs(true);
\r
567 configureTableButtons();
\r
569 } else if (e.getSource() == jobs_contextmenu_edit) {
\r
570 if (selectedJobs.size() == 1) {
\r
571 RecordJob selectedJob = selectedJobs.get(0);
\r
572 JobDialog jobDialog = new JobDialog(SwingGUI.this, selectedJob, appLayer);
\r
573 jobDialog.showDialog();
\r
574 configureTableButtons();
\r
576 } else if (e.getSource() == jobs_contextmenu_showerror) {
\r
577 if (selectedJobs.size() == 1) {
\r
578 RecordJob selectedJob = selectedJobs.get(0);
\r
579 DemoRecorderUtils.showNonCriticalErrorDialog(selectedJob.getLastException());
\r
581 } else if (e.getSource() == jobs_contextmenu_resetstate_waiting) {
\r
582 for (RecordJob job : selectedJobs) {
\r
583 job.setState(RecordJob.State.WAITING);
\r
585 } else if (e.getSource() == jobs_contextmenu_resetstate_done) {
\r
586 for (RecordJob job : selectedJobs) {
\r
587 if (job.getState() == State.ERROR_PLUGIN) {
\r
588 job.setState(RecordJob.State.DONE);
\r
591 } else if (e.getSource() == jobs_contextmenu_start) {
\r
592 appLayer.recordSelectedJobs(selectedJobs);
\r
593 if (appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {
\r
594 processing_start.setEnabled(false);
\r
595 processing_stop.setEnabled(true);
\r
596 statusBar.showState(true);
\r
598 } else if (e.getSource() == jobs_contextmenu_duplicate) {
\r
599 if (selectedJobs.size() > 0) {
\r
600 this.duplicateRecordJobs(selectedJobs);
\r
601 //select all new duplicates in the table automatically
\r
602 jobsTable.setRowSelectionInterval(jobsTable.getRowCount() - selectedJobs.size(), jobsTable.getRowCount() - 1);
\r
603 configureTableButtons();
\r
605 } else if (e.getSource() == jobs_contextmenu_applytempl) {
\r
606 if (selectedTemplates.size() == 1 && selectedJobs.size() > 0) {
\r
607 RecordJobTemplate template = (RecordJobTemplate) selectedTemplates.get(0);
\r
608 ApplyTemplateDialog applyDialog = new ApplyTemplateDialog(SwingGUI.this, template, selectedJobs);
\r
609 applyDialog.showDialog();
\r
611 } else if (jobs_contextmenu_runPluginMenuItems.contains(e.getSource())) {
\r
612 int index = jobs_contextmenu_runPluginMenuItems.indexOf(e.getSource());
\r
613 EncoderPlugin selectedPlugin = appLayer.getEncoderPlugins().get(index);
\r
615 appLayer.executePluginForSelectedJobs(selectedPlugin, selectedJobs);
\r
616 if (appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {
\r
617 processing_start.setEnabled(false);
\r
618 processing_stop.setEnabled(true);
\r
619 statusBar.showState(true);
\r
624 private void duplicateRecordJobs(List<RecordJob> jobs) {
\r
625 String nameSuffix = appLayer.getPreferences().getProperty(NDRPreferences.MAIN_APPLICATION, Preferences.JOB_NAME_APPEND_DUPLICATE);
\r
626 for (RecordJob job : jobs) {
\r
627 RecordJob newJob = appLayer.createRecordJob(
\r
628 job.getJobName() + nameSuffix,
\r
629 job.getEnginePath(),
\r
630 job.getEngineParameters(),
\r
632 job.getRelativeDemoPath(),
\r
633 job.getDpVideoPath(),
\r
634 job.getVideoDestination(),
\r
635 job.getExecuteBeforeCap(),
\r
636 job.getExecuteAfterCap(),
\r
637 job.getStartSecond(),
\r
640 newJob.setEncoderPluginSettings(job.getEncoderPluginSettings());
\r
646 private class TemplateButtonActionListener implements ActionListener {
\r
647 public void actionPerformed(ActionEvent e) {
\r
648 if (e.getSource() == templ_create) {
\r
649 RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();
\r
650 JobDialog jobDialog = new JobDialog(SwingGUI.this, tableModel, templatesTable, appLayer);
\r
651 jobDialog.showDialog();
\r
652 configureTableButtons();
\r
654 else if (e.getSource() == templ_createFromJob) {
\r
655 this.createTemplateFromJob();
\r
656 configureTableButtons();
\r
658 else if (e.getSource() == templ_delete || e.getSource() == templ_contextmenu_delete) {
\r
659 int result = JOptionPane.showConfirmDialog(SwingGUI.this, "Are you sure you want to delete the selected template(s)?", "Confirm delete", JOptionPane.YES_NO_OPTION);
\r
660 if (result == JOptionPane.YES_OPTION) {
\r
661 deleteSelectedTemplates(false);
\r
663 configureTableButtons();
\r
665 else if (e.getSource() == templ_clear) {
\r
666 int result = JOptionPane.showConfirmDialog(SwingGUI.this, "Are you sure you want to clear the template list?", "Confirm clear", JOptionPane.YES_NO_OPTION);
\r
667 if (result == JOptionPane.YES_OPTION) {
\r
668 deleteSelectedTemplates(true);
\r
670 configureTableButtons();
\r
672 else if (e.getSource() == templ_contextmenu_edit) {
\r
673 List<RecordJob> selectedTemplates = getSelectedRecordJobs(templatesTable);
\r
674 if (selectedTemplates.size() == 1) {
\r
675 RecordJobTemplate selectedTemplate = (RecordJobTemplate) selectedTemplates.get(0);
\r
676 JobDialog jobDialog = new JobDialog(SwingGUI.this, selectedTemplate, appLayer, JobDialog.EDIT_TEMPLATE);
\r
677 jobDialog.showDialog();
\r
678 configureTableButtons();
\r
681 else if (e.getSource() == templ_contextmenu_duplicate) {
\r
682 List<RecordJob> selectedTemplates = getSelectedRecordJobs(templatesTable);
\r
683 if (selectedTemplates.size() > 0) {
\r
684 this.duplicateTemplates(selectedTemplates);
\r
685 //select all new duplicates in the table automatically
\r
686 templatesTable.setRowSelectionInterval(templatesTable.getRowCount() - selectedTemplates.size(), templatesTable.getRowCount() - 1);
\r
687 configureTableButtons();
\r
692 private void createTemplateFromJob() {
\r
693 List<RecordJob> selectedJobs = getSelectedRecordJobs(jobsTable);
\r
694 if (selectedJobs.size() == 1) {
\r
695 RecordJob job = selectedJobs.get(0);
\r
696 RecordJobTemplate templ = new RecordJobTemplate(
\r
697 "Generated from job",
\r
698 "Generated from job",
\r
700 job.getEnginePath(),
\r
701 job.getEngineParameters(),
\r
702 job.getDemoFile().getParentFile(),
\r
703 job.getRelativeDemoPath(),
\r
704 job.getDpVideoPath(),
\r
705 job.getVideoDestination().getParentFile(),
\r
706 job.getExecuteBeforeCap(),
\r
707 job.getExecuteAfterCap()
\r
709 templ.setEncoderPluginSettings(job.getEncoderPluginSettings());
\r
711 RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();
\r
712 tableModel.addRecordJobTemplate(templ);
\r
716 private void duplicateTemplates(List<RecordJob> selectedTemplates) {
\r
717 for (RecordJob job : selectedTemplates) {
\r
718 RecordJobTemplate template = (RecordJobTemplate) job;
\r
719 RecordJobTemplate templ = new RecordJobTemplate(
\r
720 template.getName(),
\r
721 template.getSummary(),
\r
722 template.getJobName(),
\r
723 template.getEnginePath(),
\r
724 template.getEngineParameters(),
\r
725 template.getDemoFile(),
\r
726 template.getRelativeDemoPath(),
\r
727 template.getDpVideoPath(),
\r
728 template.getVideoDestination(),
\r
729 template.getExecuteBeforeCap(),
\r
730 template.getExecuteAfterCap()
\r
732 templ.setEncoderPluginSettings(template.getEncoderPluginSettings());
\r
734 RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();
\r
735 tableModel.addRecordJobTemplate(templ);
\r
740 private class RecordButtonActionListener implements ActionListener {
\r
742 public void actionPerformed(ActionEvent e) {
\r
743 if (e.getSource() == processing_start) {
\r
744 appLayer.startRecording();
\r
745 if (appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {
\r
746 processing_start.setEnabled(false);
\r
747 processing_stop.setEnabled(true);
\r
748 statusBar.showState(true);
\r
750 } else if (e.getSource() == processing_stop) {
\r
751 if (appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {
\r
752 appLayer.stopRecording();
\r
753 processing_stop.setEnabled(false);
\r
754 processing_stop.setText(PROCESSING_STOP_LATER);
\r
760 private void deleteSelectedJobs(boolean deleteAllJobs) {
\r
761 RecordJobsTableModel tableModel = (RecordJobsTableModel) jobsTable.getModel();
\r
762 if (deleteAllJobs) {
\r
763 int rowCount = jobsTable.getRowCount();
\r
764 for (int i = rowCount - 1; i >= 0; i--) {
\r
765 int modelRowIndex = jobsTable.convertRowIndexToModel(i);
\r
766 tableModel.deleteRecordJob(modelRowIndex, i);
\r
769 int[] selectedRows = jobsTable.getSelectedRows();
\r
770 for (int i = selectedRows.length - 1; i >= 0; i--) {
\r
771 int modelRowIndex = jobsTable.convertRowIndexToModel(selectedRows[i]);
\r
772 tableModel.deleteRecordJob(modelRowIndex, selectedRows[i]);
\r
777 private void deleteSelectedTemplates(boolean deleteAllTemplates) {
\r
778 RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();
\r
779 if (deleteAllTemplates) {
\r
780 int rowCount = templatesTable.getRowCount();
\r
781 for (int i = rowCount - 1; i >= 0; i--) {
\r
782 int modelRowIndex = templatesTable.convertRowIndexToModel(i);
\r
783 tableModel.deleteRecordJobTemplate(modelRowIndex, i);
\r
786 int[] selectedRows = templatesTable.getSelectedRows();
\r
787 for (int i = selectedRows.length - 1; i >= 0; i--) {
\r
788 int modelRowIndex = templatesTable.convertRowIndexToModel(selectedRows[i]);
\r
789 tableModel.deleteRecordJobTemplate(modelRowIndex, selectedRows[i]);
\r
792 //update the button state of buttons dealing with jobs
\r
793 this.configureTableButtons();
\r
797 * Iterates through all RecordJob objects (or just the selected ones) and returns true
\r
798 * if at least one of them has one or more has the given state(s).
\r
800 * @param justSelectedJobs
\r
803 private boolean checkJobStates(RecordJob.State[] state, boolean justSelectedJobs) {
\r
804 boolean foundState = false;
\r
805 List<RecordJob> jobsToLookAt = null;
\r
806 if (!justSelectedJobs) {
\r
807 jobsToLookAt = this.appLayer.getRecordJobs();
\r
809 jobsToLookAt = getSelectedRecordJobs(jobsTable);
\r
812 for (RecordJob currentJob : jobsToLookAt) {
\r
813 for (int i = 0; i < state.length; i++) {
\r
814 if (currentJob.getState() == state[i]) {
\r
824 * Returns the list of selected RecordJobs or RecordJobTemplates.
\r
825 * @param table jobsTable or templatesTable
\r
826 * @return list of selected RecordJobs or RecordJobTemplates
\r
828 private List<RecordJob> getSelectedRecordJobs(JXTable table) {
\r
829 List<RecordJob> list = new ArrayList<RecordJob>();
\r
830 if (table.getSelectedRowCount() > 0) {
\r
831 int[] selectedRows = table.getSelectedRows();
\r
832 for (int i = 0; i < selectedRows.length; i++) {
\r
833 int modelRowIndex = table.convertRowIndexToModel(selectedRows[i]);
\r
834 if (table == jobsTable) {
\r
835 RecordJobsTableModel tableModel = (RecordJobsTableModel) table.getModel();
\r
836 RecordJob job = tableModel.getRecordJob(modelRowIndex);
\r
841 RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) table.getModel();
\r
842 RecordJobTemplate template = tableModel.getRecordJobTemplate(modelRowIndex);
\r
843 if (template != null) {
\r
844 list.add(template);
\r
853 private void configureTableButtons() {
\r
854 if (jobsTable != null) {
\r
855 if (jobsTable.getRowCount() == 0) {
\r
856 jobs_clear.setEnabled(false);
\r
857 jobs_delete.setEnabled(false);
\r
859 jobs_clear.setEnabled(true);
\r
860 jobs_delete.setEnabled(true);
\r
861 if (jobsTable.getSelectedRowCount() == 0) {
\r
862 jobs_delete.setEnabled(false);
\r
864 //go through all elements and check for attributes PROCESSING
\r
865 RecordJob.State[] lookForState = {RecordJob.State.PROCESSING};
\r
866 boolean foundState = checkJobStates(lookForState, false);
\r
868 //we have to disable the clear and delete button
\r
869 jobs_delete.setEnabled(false);
\r
873 if (templatesTable.getSelectedRowCount() == 1) {
\r
874 jobs_createFromTempl.setEnabled(true);
\r
876 jobs_createFromTempl.setEnabled(false);
\r
880 if (templatesTable != null) {
\r
881 templ_createFromJob.setEnabled(false);
\r
882 templ_delete.setEnabled(false);
\r
883 templ_clear.setEnabled(false);
\r
885 if (jobsTable != null && jobsTable.getSelectedRowCount() == 1) {
\r
886 templ_createFromJob.setEnabled(true);
\r
889 if (templatesTable.getSelectedRowCount() > 0) {
\r
890 templ_delete.setEnabled(true);
\r
893 if (templatesTable.getRowCount() > 0) {
\r
894 templ_clear.setEnabled(true);
\r
899 private class JobsTableMouseListener implements MouseListener {
\r
901 public void mouseClicked(MouseEvent e) {
\r
902 if (e != null && e.getClickCount() == 2) {
\r
903 List<RecordJob> selectedJobs = getSelectedRecordJobs(jobsTable);
\r
904 if (selectedJobs.size() == 1) {
\r
905 RecordJob selectedJob = selectedJobs.get(0);
\r
906 if (selectedJob.getState() != RecordJob.State.PROCESSING) {
\r
907 JobDialog jobDialog = new JobDialog(SwingGUI.this, selectedJob, appLayer);
\r
908 jobDialog.showDialog();
\r
912 configureTableButtons();
\r
916 public void mouseEntered(MouseEvent e) {}
\r
918 public void mouseExited(MouseEvent e) {}
\r
920 public void mousePressed(MouseEvent e) {
\r
921 this.showPopupMenu(e);
\r
924 public void mouseReleased(MouseEvent e) {
\r
925 this.showPopupMenu(e);
\r
928 private void showPopupMenu(MouseEvent e) {
\r
929 if (e.isPopupTrigger()) {
\r
930 JTable table = (JTable)(e.getSource());
\r
931 Point p = e.getPoint();
\r
932 int row = table.rowAtPoint(p);
\r
933 int[] selectedRows = table.getSelectedRows();
\r
934 //figure out whether we have to reselect the current row under the pointer,
\r
935 //which is only the case if the already selected rows don't include the one under
\r
937 boolean reSelect = true;
\r
938 for (int i = 0; i < selectedRows.length; i++) {
\r
939 if (row == selectedRows[i]) {
\r
945 if (row != -1 && reSelect) {
\r
946 table.setRowSelectionInterval(row, row);
\r
949 this.configurePopupMenu();
\r
950 configureTableButtons();
\r
951 jobsTablePopupMenu.show(e.getComponent(), e.getX(), e.getY());
\r
955 private void configurePopupMenu() {
\r
956 //Disable all buttons first
\r
957 jobs_contextmenu_edit.setEnabled(false);
\r
958 jobs_contextmenu_duplicate.setEnabled(false);
\r
959 jobs_contextmenu_applytempl.setEnabled(false);
\r
960 jobs_contextmenu_delete.setEnabled(false);
\r
961 jobs_contextmenu_resetstate_waiting.setEnabled(false);
\r
962 jobs_contextmenu_resetstate_done.setEnabled(false);
\r
963 jobs_contextmenu_showerror.setEnabled(false);
\r
964 jobs_contextmenu_start.setEnabled(false);
\r
965 for (JMenuItem pluginItem : jobs_contextmenu_runPluginMenuItems) {
\r
966 pluginItem.setEnabled(false);
\r
969 //edit, duplicate, and show error buttons
\r
970 if (jobsTable.getSelectedRowCount() == 1) {
\r
971 jobs_contextmenu_edit.setEnabled(true);
\r
973 //Show error button
\r
974 List<RecordJob> selectedJobs = getSelectedRecordJobs(jobsTable);
\r
975 RecordJob selectedJob = selectedJobs.get(0);
\r
976 if (selectedJob.getState() == RecordJob.State.ERROR || selectedJob.getState() == RecordJob.State.ERROR_PLUGIN) {
\r
977 jobs_contextmenu_showerror.setEnabled(true);
\r
981 if (jobsTable.getSelectedRowCount() > 0) {
\r
982 jobs_contextmenu_duplicate.setEnabled(true);
\r
984 RecordJob.State[] states = {RecordJob.State.PROCESSING};
\r
985 if (!checkJobStates(states, false)) {
\r
986 //none of the jobs is processing
\r
987 jobs_contextmenu_delete.setEnabled(true);
\r
988 jobs_contextmenu_resetstate_waiting.setEnabled(true);
\r
990 if (templatesTable.getSelectedRowCount() == 1) {
\r
991 jobs_contextmenu_applytempl.setEnabled(true);
\r
996 RecordJob.State[] states2 = {RecordJob.State.ERROR, RecordJob.State.DONE, RecordJob.State.PROCESSING, RecordJob.State.ERROR_PLUGIN};
\r
997 if (!checkJobStates(states2, true)) {
\r
998 //only enable start if none of the selected jobs as any of the States above
\r
999 //as the only job State that is not listed is "waiting", we only enable the button if all jobs are waiting
\r
1000 jobs_contextmenu_start.setEnabled(true);
\r
1003 //reset to 'done' button
\r
1004 RecordJob.State[] states3 = {RecordJob.State.ERROR, RecordJob.State.WAITING, RecordJob.State.PROCESSING};
\r
1005 if (!checkJobStates(states3, true)) {
\r
1006 //only enable the "reset to done" button when processes have the state DONE or ERROR_PLUGIN
\r
1007 jobs_contextmenu_resetstate_done.setEnabled(true);
\r
1010 //plugin buttons, enable only when state of the job is DONE
\r
1011 RecordJob.State[] states4 = {RecordJob.State.ERROR, RecordJob.State.WAITING, RecordJob.State.PROCESSING, RecordJob.State.ERROR_PLUGIN};
\r
1012 if (!checkJobStates(states4, true)) {
\r
1014 for (JMenuItem pluginItem : jobs_contextmenu_runPluginMenuItems) {
\r
1015 if (appLayer.getEncoderPlugins().get(counter).isEnabled()) {
\r
1016 pluginItem.setEnabled(true);
\r
1026 private class TemplatesTableMouseListener implements MouseListener {
\r
1028 public void mouseClicked(MouseEvent e) {
\r
1029 if (e != null && e.getClickCount() == 2) {
\r
1030 List<RecordJob> selectedJobs = getSelectedRecordJobs(templatesTable);
\r
1031 if (selectedJobs.size() == 1) {
\r
1032 RecordJobTemplate selectedJob = (RecordJobTemplate) selectedJobs.get(0);
\r
1033 JobDialog jobDialog = new JobDialog(SwingGUI.this, selectedJob, appLayer, JobDialog.EDIT_TEMPLATE);
\r
1034 jobDialog.showDialog();
\r
1035 configureTableButtons();
\r
1038 configureTableButtons();
\r
1042 public void mouseEntered(MouseEvent e) {}
\r
1044 public void mouseExited(MouseEvent e) {}
\r
1046 public void mousePressed(MouseEvent e) {
\r
1047 this.showPopupMenu(e);
\r
1050 public void mouseReleased(MouseEvent e) {
\r
1051 this.showPopupMenu(e);
\r
1054 private void showPopupMenu(MouseEvent e) {
\r
1055 if (e.isPopupTrigger()) {
\r
1056 JTable table = (JTable)(e.getSource());
\r
1057 Point p = e.getPoint();
\r
1058 int row = table.rowAtPoint(p);
\r
1059 int[] selectedRows = table.getSelectedRows();
\r
1060 //figure out whether we have to reselect the current row under the pointer,
\r
1061 //which is only the case if the already selected rows don't include the one under
\r
1063 boolean reSelect = true;
\r
1064 for (int i = 0; i < selectedRows.length; i++) {
\r
1065 if (row == selectedRows[i]) {
\r
1071 if (row != -1 && reSelect) {
\r
1072 table.setRowSelectionInterval(row, row);
\r
1075 this.configurePopupMenu();
\r
1076 configureTableButtons();
\r
1077 templatesTablePopupMenu.show(e.getComponent(), e.getX(), e.getY());
\r
1081 private void configurePopupMenu() {
\r
1083 templ_contextmenu_edit.setEnabled(false);
\r
1084 templ_contextmenu_duplicate.setEnabled(false);
\r
1085 templ_contextmenu_delete.setEnabled(false);
\r
1088 if (templatesTable.getSelectedRowCount() == 1) {
\r
1089 templ_contextmenu_edit.setEnabled(true);
\r
1092 //Delete and duplicate button
\r
1093 if (templatesTable.getSelectedRowCount() > 0) {
\r
1094 templ_contextmenu_delete.setEnabled(true);
\r
1095 templ_contextmenu_duplicate.setEnabled(true);
\r
1100 private void showAboutBox() {
\r
1102 InputStream inStream = ClassLoader.getSystemResourceAsStream("about.html");
\r
1103 StringBuffer out = new StringBuffer();
\r
1104 byte[] b = new byte[4096];
\r
1105 for (int n; (n = inStream.read(b)) != -1;) {
\r
1106 out.append(new String(b, 0, n));
\r
1108 String htmlString = out.toString();
\r
1109 htmlString = htmlString.replaceAll("[\\r\\n]", "");
\r
1110 JOptionPane.showMessageDialog(this, htmlString, "About", JOptionPane.PLAIN_MESSAGE);
\r
1111 } catch (IOException ex) {
\r
1112 ex.printStackTrace();
\r
1116 public void windowActivated(WindowEvent e) {}
\r
1117 public void windowClosed(WindowEvent e) {}
\r
1118 public void windowDeactivated(WindowEvent e) {}
\r
1119 public void windowDeiconified(WindowEvent e) {}
\r
1120 public void windowIconified(WindowEvent e) {}
\r
1121 public void windowOpened(WindowEvent e) {}
\r
1123 public void windowClosing(WindowEvent e) {
\r
1127 private void shutDown() {
\r
1128 if (this.appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {
\r
1129 int result = JOptionPane.showConfirmDialog(this, "There are still jobs being recorded. Are you sure you want to exit?", "Confirm close", JOptionPane.YES_NO_OPTION);
\r
1130 if (result == JOptionPane.NO_OPTION) {
\r
1134 saveTableStates(jobsTable);
\r
1135 saveTableStates(templatesTable);
\r
1136 saveTemplateTableContent();
\r
1137 this.appLayer.shutDown();
\r
1142 private void saveTemplateTableContent() {
\r
1143 File path = DemoRecorderUtils.computeLocalFile(DemoRecorderApplication.PREFERENCES_DIRNAME, TEMPLATE_TABLE_CONTENT_FILENAME);
\r
1144 RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();
\r
1145 tableModel.saveTemplateListToFile(path);
\r
1148 private Icon getIcon(String iconString) {
\r
1149 URL url = ClassLoader.getSystemResource("icons/" + iconString);
\r
1150 Icon i = new ImageIcon(url);
\r