-package com.nexuiz.demorecorder.ui.swinggui;\r
-\r
-import java.awt.Container;\r
-import java.awt.Dimension;\r
-import java.awt.Point;\r
-import java.awt.event.ActionEvent;\r
-import java.awt.event.ActionListener;\r
-import java.awt.event.MouseEvent;\r
-import java.awt.event.MouseListener;\r
-import java.awt.event.WindowEvent;\r
-import java.awt.event.WindowListener;\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.FileOutputStream;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.io.ObjectInputStream;\r
-import java.io.ObjectOutputStream;\r
-import java.net.URL;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import javax.help.HelpBroker;\r
-import javax.help.HelpSet;\r
-import javax.swing.BorderFactory;\r
-import javax.swing.Icon;\r
-import javax.swing.ImageIcon;\r
-import javax.swing.JButton;\r
-import javax.swing.JFileChooser;\r
-import javax.swing.JFrame;\r
-import javax.swing.JMenu;\r
-import javax.swing.JMenuBar;\r
-import javax.swing.JMenuItem;\r
-import javax.swing.JOptionPane;\r
-import javax.swing.JPanel;\r
-import javax.swing.JPopupMenu;\r
-import javax.swing.JScrollPane;\r
-import javax.swing.JTable;\r
-import javax.swing.UIManager;\r
-import javax.swing.border.TitledBorder;\r
-\r
-import net.miginfocom.swing.MigLayout;\r
-\r
-import org.jdesktop.swingx.JXTable;\r
-\r
-import com.nexuiz.demorecorder.application.DemoRecorderApplication;\r
-import com.nexuiz.demorecorder.application.DemoRecorderUtils;\r
-import com.nexuiz.demorecorder.application.NDRPreferences;\r
-import com.nexuiz.demorecorder.application.DemoRecorderApplication.Preferences;\r
-import com.nexuiz.demorecorder.application.jobs.RecordJob;\r
-import com.nexuiz.demorecorder.application.jobs.RecordJob.State;\r
-import com.nexuiz.demorecorder.application.plugins.EncoderPlugin;\r
-import com.nexuiz.demorecorder.ui.DemoRecorderUI;\r
-import com.nexuiz.demorecorder.ui.swinggui.tablemodels.RecordJobTemplatesTableModel;\r
-import com.nexuiz.demorecorder.ui.swinggui.tablemodels.RecordJobsTableModel;\r
-import com.nexuiz.demorecorder.ui.swinggui.utils.ShowErrorDialogExceptionHandler;\r
-import com.nexuiz.demorecorder.ui.swinggui.utils.XProperties;\r
-import com.nexuiz.demorecorder.ui.swinggui.utils.XProperties.XTableState;\r
-\r
-public class SwingGUI extends JFrame implements WindowListener, DemoRecorderUI {\r
- \r
- private static final long serialVersionUID = -7287303462488231068L;\r
- public static final String JOB_TABLE_PREFERENCES_FILENAME = "jobsTable.pref";\r
- public static final String TEMPLATE_TABLE_PREFERENCES_FILENAME = "templatesTable.pref";\r
- public static final String TEMPLATE_TABLE_CONTENT_FILENAME = "templates.dat";\r
-\r
- private DemoRecorderApplication appLayer;\r
- private PreferencesDialog preferencesDialog;\r
- \r
- private JXTable jobsTable = null;\r
- private JPopupMenu jobsTablePopupMenu;\r
- private ActionListener jobButtonActionListener = new JobButtonActionListener();\r
- private MouseListener jobsTableMouseListener = new JobsTableMouseListener();\r
- \r
- private JXTable templatesTable = null;\r
- private JPopupMenu templatesTablePopupMenu;\r
- private ActionListener templateButtonActionListener = new TemplateButtonActionListener();\r
- private MouseListener templatesTableMouseListener = new TemplatesTableMouseListener();\r
- \r
- private ActionListener recordButtonActionListener = new RecordButtonActionListener();\r
- \r
- private static final String LABEL_JOB_CREATE = "Create";\r
- private static final String LABEL_JOB_CREATE_FROM_TEMPL = "Create from template";\r
- private static final String LABEL_JOB_DELETE = "Delete";\r
- private static final String LABEL_JOB_CLEAR = "Clear";\r
- private static final String LABEL_JOB_EDIT = "Edit job";\r
- private static final String LABEL_JOB_DUPLICATE = "Duplicate job";\r
- private static final String LABEL_JOB_APPLYTEMPL = "Apply template";\r
- private static final String LABEL_JOB_START = "Start job";\r
- private static final String LABEL_JOB_SHOWERROR = "Show error message";\r
- private static final String LABEL_JOB_RESET_STATE_WAITING = "Reset job status to 'waiting'";\r
- private static final String LABEL_JOB_RESET_STATE_DONE = "Reset job status to 'done'";\r
- \r
- private static final String LABEL_TEMPL_CREATE = "Create";\r
- private static final String LABEL_TEMPL_CREATE_FROM_JOB = "Create from job";\r
- private static final String LABEL_TEMPL_DELETE = "Delete";\r
- private static final String LABEL_TEMPL_CLEAR = "Clear";\r
- private static final String LABEL_TEMPL_EDIT = "Edit template";\r
- private static final String LABEL_TEMPL_DUPLICATE = "Duplicate template";\r
- \r
- private ActionListener menuButtonActionListener = new MenuButtonActionListener();\r
- private JMenuItem fileLoadQueue = new JMenuItem("Load job queue", getIcon("fileopen.png"));\r
- private JMenuItem fileSaveQueue = new JMenuItem("Save job queue", getIcon("filesave.png"));\r
- private JMenuItem fileLoadTemplates = new JMenuItem("Load templates", getIcon("fileopen.png"));\r
- private JMenuItem fileSaveTemplates = new JMenuItem("Save templates", getIcon("filesave.png"));\r
- private JMenuItem filePreferences = new JMenuItem("Preferences", getIcon("advanced.png"));\r
- private JMenuItem fileExit = new JMenuItem("Exit", getIcon("exit.png"));\r
- private JMenuItem helpHelp = new JMenuItem("Show help", getIcon("help.png"));\r
- private JMenuItem helpAbout = new JMenuItem("About", getIcon("info.png"));\r
- private JFileChooser jobQueueSaveAsFC = new JFileChooser();\r
- private JFileChooser templatesSaveAsFC = new JFileChooser();\r
- \r
- private JButton jobs_create = new JButton(LABEL_JOB_CREATE, getIcon("edit_add.png"));\r
- private JButton jobs_createFromTempl = new JButton(LABEL_JOB_CREATE_FROM_TEMPL, getIcon("view_right_p.png"));\r
- private JButton jobs_delete = new JButton(LABEL_JOB_DELETE, getIcon("editdelete.png"));\r
- private JButton jobs_clear = new JButton(LABEL_JOB_CLEAR, getIcon("editclear.png"));\r
- private JMenuItem jobs_contextmenu_edit = new JMenuItem(LABEL_JOB_EDIT, getIcon("edit.png"));\r
- private JMenuItem jobs_contextmenu_duplicate = new JMenuItem(LABEL_JOB_DUPLICATE, getIcon("editcopy.png"));\r
- private JMenuItem jobs_contextmenu_applytempl = new JMenuItem(LABEL_JOB_APPLYTEMPL, getIcon("editpaste.png"));\r
- private JMenuItem jobs_contextmenu_delete = new JMenuItem(LABEL_JOB_DELETE, getIcon("editdelete.png"));\r
- private JMenuItem jobs_contextmenu_start = new JMenuItem(LABEL_JOB_START, getIcon("player_play.png"));\r
- private JMenuItem jobs_contextmenu_showerror = new JMenuItem(LABEL_JOB_SHOWERROR, getIcon("status_unknown.png"));\r
- private JMenuItem jobs_contextmenu_resetstate_waiting = new JMenuItem(LABEL_JOB_RESET_STATE_WAITING, getIcon("quick_restart.png"));\r
- private JMenuItem jobs_contextmenu_resetstate_done = new JMenuItem(LABEL_JOB_RESET_STATE_DONE, getIcon("quick_restart_blue.png"));\r
- private List<JMenuItem> jobs_contextmenu_runPluginMenuItems = new ArrayList<JMenuItem>();\r
- \r
- private JButton templ_create = new JButton(LABEL_TEMPL_CREATE, getIcon("edit_add.png"));\r
- private JButton templ_createFromJob = new JButton(LABEL_TEMPL_CREATE_FROM_JOB, getIcon("view_right_p.png"));\r
- private JButton templ_delete = new JButton(LABEL_TEMPL_DELETE, getIcon("editdelete.png"));\r
- private JButton templ_clear = new JButton(LABEL_TEMPL_CLEAR, getIcon("editclear.png"));\r
- private JMenuItem templ_contextmenu_edit = new JMenuItem(LABEL_TEMPL_EDIT, getIcon("edit.png"));\r
- private JMenuItem templ_contextmenu_duplicate = new JMenuItem(LABEL_TEMPL_DUPLICATE, getIcon("editcopy.png"));\r
- private JMenuItem templ_contextmenu_delete = new JMenuItem(LABEL_TEMPL_DELETE, getIcon("editdelete.png"));\r
- \r
- private static final String PROCESSING_START = "Start processing";\r
- private static final String PROCESSING_STOP_NOW = "Stop processing";\r
- private static final String PROCESSING_STOP_LATER = "Processing will stop after current job finished";\r
- private JButton processing_start = new JButton(PROCESSING_START, getIcon("player_play.png"));\r
- private JButton processing_stop = new JButton(PROCESSING_STOP_NOW, getIcon("player_pause.png"));\r
- \r
- private StatusBar statusBar = new StatusBar();\r
- \r
- private static HelpBroker mainHelpBroker = null;\r
- private static final String mainHelpSetName = "help/DemoRecorderHelp.hs";\r
-\r
- public SwingGUI(DemoRecorderApplication appLayer) {\r
- super("Nexuiz Demo Recorder v0.3");\r
- addWindowListener(this);\r
-\r
- this.appLayer = appLayer;\r
-\r
- this.setupLayout();\r
- this.setupHelp();\r
- this.preferencesDialog = new PreferencesDialog(this, appLayer);\r
-\r
- setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);\r
- // Display the window.\r
- pack();\r
- setVisible(true);\r
- //now that we have the GUI we can set the parent window for the error dialog\r
- ShowErrorDialogExceptionHandler.setParentWindow(this);\r
- }\r
-\r
- private void setupHelp() {\r
- if (mainHelpBroker == null){\r
- HelpSet mainHelpSet = null;\r
-\r
- try {\r
- URL hsURL = HelpSet.findHelpSet(null, mainHelpSetName);\r
- mainHelpSet = new HelpSet(null, hsURL);\r
- } catch (Exception e) {\r
- DemoRecorderUtils.showNonCriticalErrorDialog("Could not properly create the help", e, true);\r
- }\r
-\r
- if (mainHelpSet != null)\r
- mainHelpBroker = mainHelpSet.createHelpBroker();\r
- }\r
- }\r
-\r
- private void setupLayout() {\r
- setLayout(new MigLayout("wrap 1,insets 10", "[400:700:,grow,fill]",\r
- "[grow,fill][grow,fill][][]"));\r
- Container contentPane = getContentPane();\r
- setJMenuBar(this.buildMenu());\r
-\r
- this.setupTemplatePanel();\r
- this.setupJobPanel();\r
- this.setupRecordPanel();\r
-\r
- contentPane.add(statusBar, "south,height 23::");\r
- }\r
-\r
- private void setupTemplatePanel() {\r
- JPanel templatePanel = new JPanel(new MigLayout("", "[500:500:,grow,fill][170!,fill,grow]", "[grow,fill]"));\r
- TitledBorder templatePanelTitle = BorderFactory.createTitledBorder("Templates");\r
- templatePanel.setBorder(templatePanelTitle);\r
- getContentPane().add(templatePanel);\r
- \r
- this.setupTemplatesTable();\r
- this.loadTableStates(this.templatesTable);\r
- JScrollPane templateScrollPane = new JScrollPane(templatesTable);\r
- templatePanel.add(templateScrollPane);\r
- \r
- this.templ_create.addActionListener(this.templateButtonActionListener);\r
- this.templ_createFromJob.addActionListener(this.templateButtonActionListener);\r
- this.templ_delete.addActionListener(this.templateButtonActionListener);\r
- this.templ_clear.addActionListener(this.templateButtonActionListener);\r
- \r
- this.templ_contextmenu_edit.addActionListener(this.templateButtonActionListener);\r
- this.templ_contextmenu_duplicate.addActionListener(this.templateButtonActionListener);\r
- this.templ_contextmenu_delete.addActionListener(this.templateButtonActionListener);\r
- \r
- this.configureTableButtons();\r
- \r
- JPanel templateControlButtonPanel = new JPanel(new MigLayout("wrap 1", "fill,grow"));\r
- templateControlButtonPanel.add(this.templ_create);\r
- templateControlButtonPanel.add(this.templ_createFromJob);\r
- templateControlButtonPanel.add(this.templ_delete);\r
- templateControlButtonPanel.add(this.templ_clear);\r
- templatePanel.add(templateControlButtonPanel);\r
- }\r
-\r
- private void setupJobPanel() {\r
- JPanel jobPanel = new JPanel(new MigLayout("", "[500:500:,grow,fill][170!,fill,grow]", "[grow,fill]"));\r
- TitledBorder jobPanelTitle = BorderFactory.createTitledBorder("Jobs");\r
- jobPanel.setBorder(jobPanelTitle);\r
- getContentPane().add(jobPanel);\r
-\r
- this.setupJobsTable();\r
- this.loadTableStates(this.jobsTable);\r
- \r
- JScrollPane jobScrollPane = new JScrollPane(jobsTable);\r
- jobPanel.add(jobScrollPane);\r
- \r
- this.jobs_create.addActionListener(this.jobButtonActionListener);\r
- this.jobs_createFromTempl.addActionListener(this.jobButtonActionListener);\r
- this.jobs_delete.addActionListener(this.jobButtonActionListener);\r
- this.jobs_clear.addActionListener(this.jobButtonActionListener);\r
- \r
- this.jobs_contextmenu_edit.addActionListener(this.jobButtonActionListener);\r
- this.jobs_contextmenu_duplicate.addActionListener(this.jobButtonActionListener);\r
- this.jobs_contextmenu_applytempl.addActionListener(this.jobButtonActionListener);\r
- this.jobs_contextmenu_delete.addActionListener(this.jobButtonActionListener);\r
- this.jobs_contextmenu_start.addActionListener(this.jobButtonActionListener);\r
- this.jobs_contextmenu_showerror.addActionListener(this.jobButtonActionListener);\r
- this.jobs_contextmenu_resetstate_waiting.addActionListener(this.jobButtonActionListener);\r
- this.jobs_contextmenu_resetstate_done.addActionListener(this.jobButtonActionListener);\r
- \r
- //initialize button states\r
- configureTableButtons();\r
- \r
- JPanel jobControlButtonPanel = new JPanel(new MigLayout("wrap 1", "fill,grow"));\r
- jobControlButtonPanel.add(this.jobs_create);\r
- jobControlButtonPanel.add(this.jobs_createFromTempl);\r
- jobControlButtonPanel.add(this.jobs_delete);\r
- jobControlButtonPanel.add(this.jobs_clear);\r
- jobPanel.add(jobControlButtonPanel);\r
- }\r
- \r
- private void setupJobsTable() {\r
- RecordJobsTableModel tableModel = new RecordJobsTableModel(this.appLayer);\r
- jobsTable = new JXTable(tableModel);\r
- jobsTable.setColumnControlVisible(true);\r
- jobsTable.setPreferredScrollableViewportSize(new Dimension(400, 100));\r
- jobsTable.addMouseListener(this.jobsTableMouseListener);\r
- }\r
- \r
- private void setupTemplatesTable() {\r
- RecordJobTemplatesTableModel tableModel = new RecordJobTemplatesTableModel();\r
- templatesTable = new JXTable(tableModel);\r
- templatesTable.setColumnControlVisible(true);\r
- templatesTable.setPreferredScrollableViewportSize(new Dimension(400, 100));\r
- templatesTable.addMouseListener(this.templatesTableMouseListener);\r
- }\r
-\r
- private void setupRecordPanel() {\r
- JPanel recButtonPanel = new JPanel(new MigLayout());\r
- recButtonPanel.add(processing_start);\r
- recButtonPanel.add(processing_stop);\r
- processing_stop.setEnabled(false);\r
- processing_start.addActionListener(recordButtonActionListener);\r
- processing_stop.addActionListener(recordButtonActionListener);\r
- getContentPane().add(recButtonPanel);\r
- }\r
-\r
- public static void setSystemLAF() {\r
- try {\r
- // Set System L&F\r
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());\r
- } catch (Exception e) {\r
- }\r
- }\r
- \r
- public void RecordJobPropertiesChange(RecordJob job) {\r
- RecordJobsTableModel jobsTableModel = (RecordJobsTableModel) this.jobsTable.getModel();\r
- List<RecordJob> recordJobs = jobsTableModel.getRecordJobs();\r
- int jobIndex = recordJobs.indexOf(job);\r
- if (jobIndex == -1) {\r
- //new job\r
- recordJobs.add(job);\r
- //add job at the end of the table:\r
- int position = jobsTableModel.getRowCount() - 1;\r
- jobsTableModel.fireTableRowsInserted(position, position);\r
- } else {\r
- //job already existed\r
- jobIndex = this.jobsTable.convertRowIndexToView(jobIndex); //convert due to possible view sorting\r
- jobsTableModel.fireTableRowsUpdated(jobIndex, jobIndex);\r
- }\r
- }\r
-\r
- public void recordingFinished() {\r
- JOptionPane.showMessageDialog(SwingGUI.this, "Finished recording all jobs", "Recording done", JOptionPane.INFORMATION_MESSAGE);\r
- statusBar.showState(false);\r
- processing_start.setEnabled(true);\r
- processing_stop.setEnabled(false);\r
- processing_stop.setText(PROCESSING_STOP_NOW);\r
- }\r
-\r
- private JMenuBar buildMenu() {\r
- JMenuBar menuBar = new JMenuBar();\r
-\r
- JMenu fileMenu = new JMenu("File");\r
- fileMenu.add(fileLoadQueue);\r
- fileMenu.add(fileSaveQueue);\r
- fileMenu.add(fileLoadTemplates);\r
- fileMenu.add(fileSaveTemplates);\r
- fileMenu.add(filePreferences);\r
- fileMenu.add(fileExit);\r
- menuBar.add(fileMenu);\r
- \r
- fileLoadQueue.addActionListener(menuButtonActionListener);\r
- fileSaveQueue.addActionListener(menuButtonActionListener);\r
- fileLoadTemplates.addActionListener(menuButtonActionListener);\r
- fileSaveTemplates.addActionListener(menuButtonActionListener);\r
- filePreferences.addActionListener(menuButtonActionListener);\r
- fileExit.addActionListener(menuButtonActionListener);\r
-\r
- JMenu helpMenu = new JMenu("Help");\r
- helpMenu.add(helpHelp);\r
- helpMenu.add(helpAbout);\r
- menuBar.add(helpMenu);\r
- \r
- helpHelp.addActionListener(menuButtonActionListener);\r
- helpAbout.addActionListener(menuButtonActionListener);\r
- \r
- this.setupEncoderPluginButtons();\r
- \r
- this.jobsTablePopupMenu = new JPopupMenu();\r
- this.jobsTablePopupMenu.add(jobs_contextmenu_edit);\r
- this.jobsTablePopupMenu.add(jobs_contextmenu_duplicate);\r
- this.jobsTablePopupMenu.add(jobs_contextmenu_applytempl);\r
- this.jobsTablePopupMenu.add(jobs_contextmenu_delete);\r
- this.jobsTablePopupMenu.add(jobs_contextmenu_start);\r
- //add JMenus for plugins\r
- for (JMenuItem menuItem : jobs_contextmenu_runPluginMenuItems) {\r
- this.jobsTablePopupMenu.add(menuItem);\r
- }\r
- this.jobsTablePopupMenu.add(jobs_contextmenu_showerror);\r
- this.jobsTablePopupMenu.add(jobs_contextmenu_resetstate_waiting);\r
- this.jobsTablePopupMenu.add(jobs_contextmenu_resetstate_done);\r
- \r
- \r
- \r
- \r
- this.templatesTablePopupMenu = new JPopupMenu();\r
- this.templatesTablePopupMenu.add(templ_contextmenu_edit);\r
- this.templatesTablePopupMenu.add(templ_contextmenu_duplicate);\r
- this.templatesTablePopupMenu.add(templ_contextmenu_delete);\r
-\r
- return menuBar;\r
- }\r
- \r
- private void setupEncoderPluginButtons() {\r
- for (EncoderPlugin plugin : appLayer.getEncoderPlugins()) {\r
- JMenuItem pluginMenuItem = new JMenuItem("Just run " + plugin.getName() + " plugin", getIcon("package.png"));\r
- pluginMenuItem.addActionListener(jobButtonActionListener);\r
- this.jobs_contextmenu_runPluginMenuItems.add(pluginMenuItem);\r
- }\r
- }\r
-\r
- private void saveTableStates(JXTable table) {\r
- String fileName;\r
- if (table == jobsTable) {\r
- fileName = JOB_TABLE_PREFERENCES_FILENAME;\r
- } else {\r
- fileName = TEMPLATE_TABLE_PREFERENCES_FILENAME;\r
- }\r
- String exceptionMessage = "An error occurred while trying to save the table state file " + fileName;\r
- \r
- XProperties.XTableProperty t = new XProperties.XTableProperty();\r
- XTableState tableState;\r
- try {\r
- tableState = (XTableState) t.getSessionState(table);\r
- } catch (Exception e) { //most likely ClassCastException\r
- DemoRecorderUtils.showNonCriticalErrorDialog(exceptionMessage, e, true);\r
- return;\r
- }\r
- \r
- File tableStateFile = DemoRecorderUtils.computeLocalFile(DemoRecorderApplication.PREFERENCES_DIRNAME, fileName);\r
- DemoRecorderUtils.attemptFileCreation(tableStateFile);\r
- \r
- try {\r
- FileOutputStream fout = new FileOutputStream(tableStateFile);\r
- ObjectOutputStream oos = new ObjectOutputStream(fout);\r
- oos.writeObject(tableState);\r
- oos.close();\r
- } catch (Exception e) {\r
- DemoRecorderUtils.showNonCriticalErrorDialog(exceptionMessage, e, true);\r
- }\r
- }\r
- \r
- private void loadTableStates(JXTable table) {\r
- String fileName;\r
- if (table == jobsTable) {\r
- fileName = JOB_TABLE_PREFERENCES_FILENAME;\r
- } else {\r
- fileName = TEMPLATE_TABLE_PREFERENCES_FILENAME;\r
- }\r
- \r
- XProperties.XTableProperty t = new XProperties.XTableProperty();\r
- \r
- File tableStateFile = DemoRecorderUtils.computeLocalFile(DemoRecorderApplication.PREFERENCES_DIRNAME, fileName);\r
- \r
- XTableState tableState;\r
- \r
- try {\r
- FileInputStream fin = new FileInputStream(tableStateFile);\r
- ObjectInputStream ois = new ObjectInputStream(fin);\r
- tableState = (XTableState) ois.readObject();\r
- t.setSessionState(table, tableState);\r
- } catch (Exception e) {\r
- //manually hide columns\r
- if (table == jobsTable) {\r
- //re-create table to be sure\r
- this.setupJobsTable();\r
- //manually hide some columns\r
- jobsTable.getColumnExt(RecordJobsTableModel.EXECUTE_AFTER_CAP).setVisible(false);\r
- jobsTable.getColumnExt(RecordJobsTableModel.EXECUTE_BEFORE_CAP).setVisible(false);\r
- jobsTable.getColumnExt(RecordJobsTableModel.VIDEO_DESTINATION_PATH).setVisible(false);\r
- jobsTable.getColumnExt(RecordJobsTableModel.DPVIDEO_PATH).setVisible(false);\r
- jobsTable.getColumnExt(RecordJobsTableModel.RELATIVE_DEMO_PATH).setVisible(false);\r
- jobsTable.getColumnExt(RecordJobsTableModel.ENGINE_PARAMETERS).setVisible(false);\r
- jobsTable.getColumnExt(RecordJobsTableModel.ENGINE_PATH).setVisible(false);\r
- } else {\r
- //re-create table to be sure\r
- this.setupTemplatesTable();\r
- //manually hide some columns\r
- templatesTable.getColumnExt(RecordJobTemplatesTableModel.EXECUTE_AFTER_CAP).setVisible(false);\r
- templatesTable.getColumnExt(RecordJobTemplatesTableModel.EXECUTE_BEFORE_CAP).setVisible(false);\r
- templatesTable.getColumnExt(RecordJobTemplatesTableModel.VIDEO_DESTINATION_PATH).setVisible(false);\r
- templatesTable.getColumnExt(RecordJobTemplatesTableModel.DPVIDEO_PATH).setVisible(false);\r
- templatesTable.getColumnExt(RecordJobTemplatesTableModel.RELATIVE_DEMO_PATH).setVisible(false);\r
- templatesTable.getColumnExt(RecordJobTemplatesTableModel.DEMO_FILE_PATH).setVisible(false);\r
- templatesTable.getColumnExt(RecordJobTemplatesTableModel.ENGINE_PARAMETERS).setVisible(false);\r
- templatesTable.getColumnExt(RecordJobTemplatesTableModel.ENGINE_PATH).setVisible(false);\r
- templatesTable.getColumnExt(RecordJobTemplatesTableModel.JOB_NAME).setVisible(false);\r
- }\r
- }\r
- }\r
- \r
- private class MenuButtonActionListener implements ActionListener {\r
-\r
- public void actionPerformed(ActionEvent e) {\r
- if (e.getSource() == fileLoadQueue) {\r
- int result = jobQueueSaveAsFC.showOpenDialog(SwingGUI.this);\r
- if (result == JFileChooser.APPROVE_OPTION) {\r
- File selectedFile = jobQueueSaveAsFC.getSelectedFile();\r
- if (selectedFile.isFile()) {\r
- RecordJobsTableModel tableModel = (RecordJobsTableModel) jobsTable.getModel();\r
- tableModel.loadNewJobQueue(SwingGUI.this, selectedFile, jobsTable);\r
- configureTableButtons();\r
- }\r
- }\r
- \r
- } else if (e.getSource() == fileSaveQueue) {\r
- int result = jobQueueSaveAsFC.showSaveDialog(SwingGUI.this);\r
- if (result == JFileChooser.APPROVE_OPTION) {\r
- File selectedFile = jobQueueSaveAsFC.getSelectedFile();\r
- if (!DemoRecorderUtils.getFileExtension(selectedFile).equals("queue")) {\r
- //if file is not a .queue file, make it one\r
- selectedFile = new File(selectedFile.getAbsoluteFile() + ".queue");\r
- }\r
- if (selectedFile.exists()) {\r
- int confirm = JOptionPane.showConfirmDialog(SwingGUI.this, "File already exists. Are you sure you want to overwrite it?", "Confirm overwrite", JOptionPane.YES_NO_OPTION);\r
- if (confirm == JOptionPane.NO_OPTION) {\r
- return;\r
- }\r
- }\r
- appLayer.saveJobQueue(selectedFile);\r
- }\r
- } else if (e.getSource() == fileLoadTemplates) {\r
- int result = templatesSaveAsFC.showOpenDialog(SwingGUI.this);\r
- if (result == JFileChooser.APPROVE_OPTION) {\r
- File selectedFile = templatesSaveAsFC.getSelectedFile();\r
- if (selectedFile.isFile()) {\r
- RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();\r
- tableModel.loadNewTemplateList(SwingGUI.this, selectedFile, templatesTable);\r
- configureTableButtons();\r
- }\r
- }\r
- } else if (e.getSource() == fileSaveTemplates) {\r
- int result = templatesSaveAsFC.showSaveDialog(SwingGUI.this);\r
- if (result == JFileChooser.APPROVE_OPTION) {\r
- File selectedFile = templatesSaveAsFC.getSelectedFile();\r
- if (!DemoRecorderUtils.getFileExtension(selectedFile).equals("templ")) {\r
- selectedFile = new File(selectedFile.getAbsoluteFile() + ".templ");\r
- }\r
- if (selectedFile.exists()) {\r
- int confirm = JOptionPane.showConfirmDialog(SwingGUI.this, "File already exists. Are you sure you want to overwrite it?", "Confirm overwrite", JOptionPane.YES_NO_OPTION);\r
- if (confirm == JOptionPane.NO_OPTION) {\r
- return;\r
- }\r
- }\r
- RecordJobTemplatesTableModel model = (RecordJobTemplatesTableModel) templatesTable.getModel();\r
- model.saveTemplateListToFile(selectedFile);\r
- }\r
- } else if (e.getSource() == filePreferences) {\r
- preferencesDialog.showDialog();\r
- } else if (e.getSource() == fileExit) {\r
- shutDown();\r
- } else if (e.getSource() == helpHelp) {\r
- if (mainHelpBroker != null) {\r
- mainHelpBroker.setDisplayed(true);\r
- }\r
- } else if (e.getSource() == helpAbout) {\r
- showAboutBox();\r
- }\r
- }\r
- \r
- }\r
-\r
- /**\r
- * Listens to the clicks on buttons that are in the job panel (next to the jobs table)\r
- * or its context menu.\r
- */\r
- private class JobButtonActionListener implements ActionListener {\r
-\r
- public void actionPerformed(ActionEvent e) {\r
- List<RecordJob> selectedJobs = getSelectedRecordJobs(jobsTable);\r
- List<RecordJob> selectedTemplates = getSelectedRecordJobs(templatesTable);\r
- if (e.getSource() == jobs_create) {\r
- JobDialog jobDialog = new JobDialog(SwingGUI.this, appLayer);\r
- jobDialog.showDialog();\r
- configureTableButtons();\r
- }\r
- else if (e.getSource() == jobs_createFromTempl) {\r
- if (selectedTemplates.size() != 1) {\r
- return;\r
- }\r
- RecordJobTemplate template = (RecordJobTemplate) selectedTemplates.get(0);\r
-// JobDialog jobDialog = new JobDialog(SwingGUI.this, template, appLayer);\r
- JobDialog jobDialog = new JobDialog(SwingGUI.this, template, appLayer, JobDialog.CREATE_JOB_FROM_TEMPLATE);\r
- jobDialog.showDialog();\r
- configureTableButtons();\r
- }\r
- else if (e.getSource() == jobs_delete || e.getSource() == jobs_contextmenu_delete) {\r
- int result = JOptionPane.showConfirmDialog(SwingGUI.this, "Are you sure you want to delete the selected job(s)?", "Confirm delete", JOptionPane.YES_NO_OPTION);\r
- if (result == JOptionPane.YES_OPTION) {\r
- deleteSelectedJobs(false);\r
- configureTableButtons();\r
- }\r
- }\r
- else if (e.getSource() == jobs_clear) {\r
- int result = JOptionPane.showConfirmDialog(SwingGUI.this, "Are you sure you want to clear the job list?", "Confirm clear", JOptionPane.YES_NO_OPTION);\r
- if (result == JOptionPane.YES_OPTION) {\r
- deleteSelectedJobs(true);\r
- configureTableButtons();\r
- }\r
- } else if (e.getSource() == jobs_contextmenu_edit) {\r
- if (selectedJobs.size() == 1) {\r
- RecordJob selectedJob = selectedJobs.get(0);\r
- JobDialog jobDialog = new JobDialog(SwingGUI.this, selectedJob, appLayer);\r
- jobDialog.showDialog();\r
- configureTableButtons();\r
- }\r
- } else if (e.getSource() == jobs_contextmenu_showerror) {\r
- if (selectedJobs.size() == 1) {\r
- RecordJob selectedJob = selectedJobs.get(0);\r
- DemoRecorderUtils.showNonCriticalErrorDialog(selectedJob.getLastException());\r
- }\r
- } else if (e.getSource() == jobs_contextmenu_resetstate_waiting) {\r
- for (RecordJob job : selectedJobs) {\r
- job.setState(RecordJob.State.WAITING);\r
- }\r
- } else if (e.getSource() == jobs_contextmenu_resetstate_done) {\r
- for (RecordJob job : selectedJobs) {\r
- if (job.getState() == State.ERROR_PLUGIN) {\r
- job.setState(RecordJob.State.DONE);\r
- }\r
- }\r
- } else if (e.getSource() == jobs_contextmenu_start) {\r
- appLayer.recordSelectedJobs(selectedJobs);\r
- if (appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {\r
- processing_start.setEnabled(false);\r
- processing_stop.setEnabled(true);\r
- statusBar.showState(true);\r
- }\r
- } else if (e.getSource() == jobs_contextmenu_duplicate) {\r
- if (selectedJobs.size() > 0) {\r
- this.duplicateRecordJobs(selectedJobs);\r
- //select all new duplicates in the table automatically\r
- jobsTable.setRowSelectionInterval(jobsTable.getRowCount() - selectedJobs.size(), jobsTable.getRowCount() - 1);\r
- configureTableButtons();\r
- }\r
- } else if (e.getSource() == jobs_contextmenu_applytempl) {\r
- if (selectedTemplates.size() == 1 && selectedJobs.size() > 0) {\r
- RecordJobTemplate template = (RecordJobTemplate) selectedTemplates.get(0);\r
- ApplyTemplateDialog applyDialog = new ApplyTemplateDialog(SwingGUI.this, template, selectedJobs);\r
- applyDialog.showDialog();\r
- }\r
- } else if (jobs_contextmenu_runPluginMenuItems.contains(e.getSource())) {\r
- int index = jobs_contextmenu_runPluginMenuItems.indexOf(e.getSource());\r
- EncoderPlugin selectedPlugin = appLayer.getEncoderPlugins().get(index);\r
- \r
- appLayer.executePluginForSelectedJobs(selectedPlugin, selectedJobs);\r
- if (appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {\r
- processing_start.setEnabled(false);\r
- processing_stop.setEnabled(true);\r
- statusBar.showState(true);\r
- }\r
- }\r
- }\r
- \r
- private void duplicateRecordJobs(List<RecordJob> jobs) {\r
- String nameSuffix = appLayer.getPreferences().getProperty(NDRPreferences.MAIN_APPLICATION, Preferences.JOB_NAME_APPEND_DUPLICATE);\r
- for (RecordJob job : jobs) {\r
- RecordJob newJob = appLayer.createRecordJob(\r
- job.getJobName() + nameSuffix,\r
- job.getEnginePath(),\r
- job.getEngineParameters(),\r
- job.getDemoFile(),\r
- job.getRelativeDemoPath(),\r
- job.getDpVideoPath(),\r
- job.getVideoDestination(),\r
- job.getExecuteBeforeCap(),\r
- job.getExecuteAfterCap(),\r
- job.getStartSecond(),\r
- job.getEndSecond()\r
- );\r
- newJob.setEncoderPluginSettings(job.getEncoderPluginSettings());\r
- }\r
- }\r
- \r
- }\r
- \r
- private class TemplateButtonActionListener implements ActionListener {\r
- public void actionPerformed(ActionEvent e) {\r
- if (e.getSource() == templ_create) {\r
- RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();\r
- JobDialog jobDialog = new JobDialog(SwingGUI.this, tableModel, templatesTable, appLayer);\r
- jobDialog.showDialog();\r
- configureTableButtons();\r
- }\r
- else if (e.getSource() == templ_createFromJob) {\r
- this.createTemplateFromJob();\r
- configureTableButtons();\r
- }\r
- else if (e.getSource() == templ_delete || e.getSource() == templ_contextmenu_delete) {\r
- int result = JOptionPane.showConfirmDialog(SwingGUI.this, "Are you sure you want to delete the selected template(s)?", "Confirm delete", JOptionPane.YES_NO_OPTION);\r
- if (result == JOptionPane.YES_OPTION) {\r
- deleteSelectedTemplates(false);\r
- }\r
- configureTableButtons();\r
- }\r
- else if (e.getSource() == templ_clear) {\r
- int result = JOptionPane.showConfirmDialog(SwingGUI.this, "Are you sure you want to clear the template list?", "Confirm clear", JOptionPane.YES_NO_OPTION);\r
- if (result == JOptionPane.YES_OPTION) {\r
- deleteSelectedTemplates(true);\r
- }\r
- configureTableButtons();\r
- }\r
- else if (e.getSource() == templ_contextmenu_edit) {\r
- List<RecordJob> selectedTemplates = getSelectedRecordJobs(templatesTable);\r
- if (selectedTemplates.size() == 1) {\r
- RecordJobTemplate selectedTemplate = (RecordJobTemplate) selectedTemplates.get(0);\r
- JobDialog jobDialog = new JobDialog(SwingGUI.this, selectedTemplate, appLayer, JobDialog.EDIT_TEMPLATE);\r
- jobDialog.showDialog();\r
- configureTableButtons();\r
- }\r
- }\r
- else if (e.getSource() == templ_contextmenu_duplicate) {\r
- List<RecordJob> selectedTemplates = getSelectedRecordJobs(templatesTable);\r
- if (selectedTemplates.size() > 0) {\r
- this.duplicateTemplates(selectedTemplates);\r
- //select all new duplicates in the table automatically\r
- templatesTable.setRowSelectionInterval(templatesTable.getRowCount() - selectedTemplates.size(), templatesTable.getRowCount() - 1);\r
- configureTableButtons();\r
- }\r
- }\r
- }\r
- \r
- private void createTemplateFromJob() {\r
- List<RecordJob> selectedJobs = getSelectedRecordJobs(jobsTable);\r
- if (selectedJobs.size() == 1) {\r
- RecordJob job = selectedJobs.get(0);\r
- RecordJobTemplate templ = new RecordJobTemplate(\r
- "Generated from job",\r
- "Generated from job",\r
- job.getJobName(),\r
- job.getEnginePath(),\r
- job.getEngineParameters(),\r
- job.getDemoFile().getParentFile(),\r
- job.getRelativeDemoPath(),\r
- job.getDpVideoPath(),\r
- job.getVideoDestination().getParentFile(),\r
- job.getExecuteBeforeCap(),\r
- job.getExecuteAfterCap()\r
- );\r
- templ.setEncoderPluginSettings(job.getEncoderPluginSettings());\r
- \r
- RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();\r
- tableModel.addRecordJobTemplate(templ);\r
- }\r
- }\r
- \r
- private void duplicateTemplates(List<RecordJob> selectedTemplates) {\r
- for (RecordJob job : selectedTemplates) {\r
- RecordJobTemplate template = (RecordJobTemplate) job;\r
- RecordJobTemplate templ = new RecordJobTemplate(\r
- template.getName(),\r
- template.getSummary(),\r
- template.getJobName(),\r
- template.getEnginePath(),\r
- template.getEngineParameters(),\r
- template.getDemoFile(),\r
- template.getRelativeDemoPath(),\r
- template.getDpVideoPath(),\r
- template.getVideoDestination(),\r
- template.getExecuteBeforeCap(),\r
- template.getExecuteAfterCap()\r
- );\r
- templ.setEncoderPluginSettings(template.getEncoderPluginSettings());\r
- \r
- RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();\r
- tableModel.addRecordJobTemplate(templ);\r
- }\r
- }\r
- }\r
- \r
- private class RecordButtonActionListener implements ActionListener {\r
-\r
- public void actionPerformed(ActionEvent e) {\r
- if (e.getSource() == processing_start) {\r
- appLayer.startRecording();\r
- if (appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {\r
- processing_start.setEnabled(false);\r
- processing_stop.setEnabled(true);\r
- statusBar.showState(true);\r
- }\r
- } else if (e.getSource() == processing_stop) {\r
- if (appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {\r
- appLayer.stopRecording();\r
- processing_stop.setEnabled(false);\r
- processing_stop.setText(PROCESSING_STOP_LATER);\r
- }\r
- }\r
- }\r
- }\r
- \r
- private void deleteSelectedJobs(boolean deleteAllJobs) {\r
- RecordJobsTableModel tableModel = (RecordJobsTableModel) jobsTable.getModel();\r
- if (deleteAllJobs) {\r
- int rowCount = jobsTable.getRowCount();\r
- for (int i = rowCount - 1; i >= 0; i--) {\r
- int modelRowIndex = jobsTable.convertRowIndexToModel(i);\r
- tableModel.deleteRecordJob(modelRowIndex, i);\r
- }\r
- } else {\r
- int[] selectedRows = jobsTable.getSelectedRows();\r
- for (int i = selectedRows.length - 1; i >= 0; i--) {\r
- int modelRowIndex = jobsTable.convertRowIndexToModel(selectedRows[i]);\r
- tableModel.deleteRecordJob(modelRowIndex, selectedRows[i]);\r
- }\r
- }\r
- }\r
- \r
- private void deleteSelectedTemplates(boolean deleteAllTemplates) {\r
- RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();\r
- if (deleteAllTemplates) {\r
- int rowCount = templatesTable.getRowCount();\r
- for (int i = rowCount - 1; i >= 0; i--) {\r
- int modelRowIndex = templatesTable.convertRowIndexToModel(i);\r
- tableModel.deleteRecordJobTemplate(modelRowIndex, i);\r
- }\r
- } else {\r
- int[] selectedRows = templatesTable.getSelectedRows();\r
- for (int i = selectedRows.length - 1; i >= 0; i--) {\r
- int modelRowIndex = templatesTable.convertRowIndexToModel(selectedRows[i]);\r
- tableModel.deleteRecordJobTemplate(modelRowIndex, selectedRows[i]);\r
- }\r
- }\r
- //update the button state of buttons dealing with jobs\r
- this.configureTableButtons();\r
- }\r
- \r
- /**\r
- * Iterates through all RecordJob objects (or just the selected ones) and returns true\r
- * if at least one of them has one or more has the given state(s).\r
- * @param state\r
- * @param justSelectedJobs\r
- * @return\r
- */\r
- private boolean checkJobStates(RecordJob.State[] state, boolean justSelectedJobs) {\r
- boolean foundState = false;\r
- List<RecordJob> jobsToLookAt = null;\r
- if (!justSelectedJobs) {\r
- jobsToLookAt = this.appLayer.getRecordJobs();\r
- } else {\r
- jobsToLookAt = getSelectedRecordJobs(jobsTable);\r
- }\r
- \r
- for (RecordJob currentJob : jobsToLookAt) {\r
- for (int i = 0; i < state.length; i++) {\r
- if (currentJob.getState() == state[i]) {\r
- foundState = true;\r
- break;\r
- }\r
- }\r
- }\r
- return foundState;\r
- }\r
- \r
- /**\r
- * Returns the list of selected RecordJobs or RecordJobTemplates.\r
- * @param table jobsTable or templatesTable\r
- * @return list of selected RecordJobs or RecordJobTemplates\r
- */\r
- private List<RecordJob> getSelectedRecordJobs(JXTable table) {\r
- List<RecordJob> list = new ArrayList<RecordJob>();\r
- if (table.getSelectedRowCount() > 0) {\r
- int[] selectedRows = table.getSelectedRows();\r
- for (int i = 0; i < selectedRows.length; i++) {\r
- int modelRowIndex = table.convertRowIndexToModel(selectedRows[i]);\r
- if (table == jobsTable) {\r
- RecordJobsTableModel tableModel = (RecordJobsTableModel) table.getModel();\r
- RecordJob job = tableModel.getRecordJob(modelRowIndex);\r
- if (job != null) {\r
- list.add(job);\r
- }\r
- } else {\r
- RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) table.getModel();\r
- RecordJobTemplate template = tableModel.getRecordJobTemplate(modelRowIndex);\r
- if (template != null) {\r
- list.add(template);\r
- }\r
- }\r
- }\r
- }\r
- \r
- return list;\r
- }\r
- \r
- private void configureTableButtons() {\r
- if (jobsTable != null) {\r
- if (jobsTable.getRowCount() == 0) {\r
- jobs_clear.setEnabled(false);\r
- jobs_delete.setEnabled(false);\r
- } else {\r
- jobs_clear.setEnabled(true);\r
- jobs_delete.setEnabled(true);\r
- if (jobsTable.getSelectedRowCount() == 0) {\r
- jobs_delete.setEnabled(false);\r
- } else {\r
- //go through all elements and check for attributes PROCESSING\r
- RecordJob.State[] lookForState = {RecordJob.State.PROCESSING};\r
- boolean foundState = checkJobStates(lookForState, false);\r
- if (foundState) {\r
- //we have to disable the clear and delete button\r
- jobs_delete.setEnabled(false);\r
- }\r
- }\r
- }\r
- if (templatesTable.getSelectedRowCount() == 1) {\r
- jobs_createFromTempl.setEnabled(true);\r
- } else {\r
- jobs_createFromTempl.setEnabled(false);\r
- }\r
- }\r
- \r
- if (templatesTable != null) {\r
- templ_createFromJob.setEnabled(false);\r
- templ_delete.setEnabled(false);\r
- templ_clear.setEnabled(false);\r
- \r
- if (jobsTable != null && jobsTable.getSelectedRowCount() == 1) {\r
- templ_createFromJob.setEnabled(true);\r
- }\r
- \r
- if (templatesTable.getSelectedRowCount() > 0) {\r
- templ_delete.setEnabled(true);\r
- }\r
- \r
- if (templatesTable.getRowCount() > 0) {\r
- templ_clear.setEnabled(true);\r
- }\r
- }\r
- }\r
- \r
- private class JobsTableMouseListener implements MouseListener {\r
-\r
- public void mouseClicked(MouseEvent e) {\r
- if (e != null && e.getClickCount() == 2) {\r
- List<RecordJob> selectedJobs = getSelectedRecordJobs(jobsTable);\r
- if (selectedJobs.size() == 1) {\r
- RecordJob selectedJob = selectedJobs.get(0);\r
- if (selectedJob.getState() != RecordJob.State.PROCESSING) {\r
- JobDialog jobDialog = new JobDialog(SwingGUI.this, selectedJob, appLayer);\r
- jobDialog.showDialog();\r
- }\r
- }\r
- } else {\r
- configureTableButtons();\r
- }\r
- }\r
-\r
- public void mouseEntered(MouseEvent e) {}\r
-\r
- public void mouseExited(MouseEvent e) {}\r
-\r
- public void mousePressed(MouseEvent e) {\r
- this.showPopupMenu(e);\r
- }\r
-\r
- public void mouseReleased(MouseEvent e) {\r
- this.showPopupMenu(e);\r
- }\r
- \r
- private void showPopupMenu(MouseEvent e) {\r
- if (e.isPopupTrigger()) {\r
- JTable table = (JTable)(e.getSource());\r
- Point p = e.getPoint();\r
- int row = table.rowAtPoint(p);\r
- int[] selectedRows = table.getSelectedRows();\r
- //figure out whether we have to reselect the current row under the pointer,\r
- //which is only the case if the already selected rows don't include the one under\r
- //the pointer yet\r
- boolean reSelect = true;\r
- for (int i = 0; i < selectedRows.length; i++) {\r
- if (row == selectedRows[i]) {\r
- reSelect = false;\r
- break;\r
- }\r
- }\r
- \r
- if (row != -1 && reSelect) {\r
- table.setRowSelectionInterval(row, row);\r
- }\r
- \r
- this.configurePopupMenu();\r
- configureTableButtons();\r
- jobsTablePopupMenu.show(e.getComponent(), e.getX(), e.getY());\r
- }\r
- }\r
- \r
- private void configurePopupMenu() {\r
- //Disable all buttons first\r
- jobs_contextmenu_edit.setEnabled(false);\r
- jobs_contextmenu_duplicate.setEnabled(false);\r
- jobs_contextmenu_applytempl.setEnabled(false);\r
- jobs_contextmenu_delete.setEnabled(false);\r
- jobs_contextmenu_resetstate_waiting.setEnabled(false);\r
- jobs_contextmenu_resetstate_done.setEnabled(false);\r
- jobs_contextmenu_showerror.setEnabled(false);\r
- jobs_contextmenu_start.setEnabled(false);\r
- for (JMenuItem pluginItem : jobs_contextmenu_runPluginMenuItems) {\r
- pluginItem.setEnabled(false);\r
- }\r
- \r
- //edit, duplicate, and show error buttons\r
- if (jobsTable.getSelectedRowCount() == 1) {\r
- jobs_contextmenu_edit.setEnabled(true);\r
- \r
- //Show error button\r
- List<RecordJob> selectedJobs = getSelectedRecordJobs(jobsTable);\r
- RecordJob selectedJob = selectedJobs.get(0);\r
- if (selectedJob.getState() == RecordJob.State.ERROR || selectedJob.getState() == RecordJob.State.ERROR_PLUGIN) {\r
- jobs_contextmenu_showerror.setEnabled(true);\r
- }\r
- }\r
- \r
- if (jobsTable.getSelectedRowCount() > 0) {\r
- jobs_contextmenu_duplicate.setEnabled(true);\r
- //Delete button\r
- RecordJob.State[] states = {RecordJob.State.PROCESSING};\r
- if (!checkJobStates(states, false)) {\r
- //none of the jobs is processing\r
- jobs_contextmenu_delete.setEnabled(true);\r
- jobs_contextmenu_resetstate_waiting.setEnabled(true);\r
- \r
- if (templatesTable.getSelectedRowCount() == 1) {\r
- jobs_contextmenu_applytempl.setEnabled(true);\r
- }\r
- }\r
- \r
- //Start button\r
- RecordJob.State[] states2 = {RecordJob.State.ERROR, RecordJob.State.DONE, RecordJob.State.PROCESSING, RecordJob.State.ERROR_PLUGIN};\r
- if (!checkJobStates(states2, true)) {\r
- //only enable start if none of the selected jobs as any of the States above\r
- //as the only job State that is not listed is "waiting", we only enable the button if all jobs are waiting\r
- jobs_contextmenu_start.setEnabled(true);\r
- }\r
- \r
- //reset to 'done' button\r
- RecordJob.State[] states3 = {RecordJob.State.ERROR, RecordJob.State.WAITING, RecordJob.State.PROCESSING};\r
- if (!checkJobStates(states3, true)) {\r
- //only enable the "reset to done" button when processes have the state DONE or ERROR_PLUGIN\r
- jobs_contextmenu_resetstate_done.setEnabled(true);\r
- }\r
- \r
- //plugin buttons, enable only when state of the job is DONE\r
- RecordJob.State[] states4 = {RecordJob.State.ERROR, RecordJob.State.WAITING, RecordJob.State.PROCESSING, RecordJob.State.ERROR_PLUGIN};\r
- if (!checkJobStates(states4, true)) {\r
- int counter = 0;\r
- for (JMenuItem pluginItem : jobs_contextmenu_runPluginMenuItems) {\r
- if (appLayer.getEncoderPlugins().get(counter).isEnabled()) {\r
- pluginItem.setEnabled(true);\r
- }\r
- counter++;\r
- }\r
- }\r
- }\r
- }\r
- \r
- }\r
- \r
- private class TemplatesTableMouseListener implements MouseListener {\r
-\r
- public void mouseClicked(MouseEvent e) {\r
- if (e != null && e.getClickCount() == 2) {\r
- List<RecordJob> selectedJobs = getSelectedRecordJobs(templatesTable);\r
- if (selectedJobs.size() == 1) {\r
- RecordJobTemplate selectedJob = (RecordJobTemplate) selectedJobs.get(0);\r
- JobDialog jobDialog = new JobDialog(SwingGUI.this, selectedJob, appLayer, JobDialog.EDIT_TEMPLATE);\r
- jobDialog.showDialog();\r
- configureTableButtons();\r
- }\r
- } else {\r
- configureTableButtons();\r
- }\r
- }\r
-\r
- public void mouseEntered(MouseEvent e) {}\r
-\r
- public void mouseExited(MouseEvent e) {}\r
-\r
- public void mousePressed(MouseEvent e) {\r
- this.showPopupMenu(e);\r
- }\r
-\r
- public void mouseReleased(MouseEvent e) {\r
- this.showPopupMenu(e);\r
- }\r
- \r
- private void showPopupMenu(MouseEvent e) {\r
- if (e.isPopupTrigger()) {\r
- JTable table = (JTable)(e.getSource());\r
- Point p = e.getPoint();\r
- int row = table.rowAtPoint(p);\r
- int[] selectedRows = table.getSelectedRows();\r
- //figure out whether we have to reselect the current row under the pointer,\r
- //which is only the case if the already selected rows don't include the one under\r
- //the pointer yet\r
- boolean reSelect = true;\r
- for (int i = 0; i < selectedRows.length; i++) {\r
- if (row == selectedRows[i]) {\r
- reSelect = false;\r
- break;\r
- }\r
- }\r
- \r
- if (row != -1 && reSelect) {\r
- table.setRowSelectionInterval(row, row);\r
- }\r
- \r
- this.configurePopupMenu();\r
- configureTableButtons();\r
- templatesTablePopupMenu.show(e.getComponent(), e.getX(), e.getY());\r
- }\r
- }\r
- \r
- private void configurePopupMenu() {\r
- //Various buttons\r
- templ_contextmenu_edit.setEnabled(false);\r
- templ_contextmenu_duplicate.setEnabled(false);\r
- templ_contextmenu_delete.setEnabled(false);\r
- \r
- //Edit button\r
- if (templatesTable.getSelectedRowCount() == 1) {\r
- templ_contextmenu_edit.setEnabled(true);\r
- }\r
- \r
- //Delete and duplicate button\r
- if (templatesTable.getSelectedRowCount() > 0) {\r
- templ_contextmenu_delete.setEnabled(true);\r
- templ_contextmenu_duplicate.setEnabled(true);\r
- }\r
- }\r
- }\r
- \r
- private void showAboutBox() {\r
- try {\r
- InputStream inStream = ClassLoader.getSystemResourceAsStream("about.html");\r
- StringBuffer out = new StringBuffer();\r
- byte[] b = new byte[4096];\r
- for (int n; (n = inStream.read(b)) != -1;) {\r
- out.append(new String(b, 0, n));\r
- }\r
- String htmlString = out.toString();\r
- htmlString = htmlString.replaceAll("[\\r\\n]", "");\r
- JOptionPane.showMessageDialog(this, htmlString, "About", JOptionPane.PLAIN_MESSAGE);\r
- } catch (IOException ex) {\r
- ex.printStackTrace();\r
- }\r
- }\r
-\r
- public void windowActivated(WindowEvent e) {}\r
- public void windowClosed(WindowEvent e) {}\r
- public void windowDeactivated(WindowEvent e) {}\r
- public void windowDeiconified(WindowEvent e) {}\r
- public void windowIconified(WindowEvent e) {}\r
- public void windowOpened(WindowEvent e) {}\r
-\r
- public void windowClosing(WindowEvent e) {\r
- this.shutDown();\r
- }\r
-\r
- private void shutDown() {\r
- if (this.appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {\r
- 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
- if (result == JOptionPane.NO_OPTION) {\r
- return;\r
- }\r
- }\r
- saveTableStates(jobsTable);\r
- saveTableStates(templatesTable);\r
- saveTemplateTableContent();\r
- this.appLayer.shutDown();\r
- this.dispose();\r
- System.exit(0);\r
- }\r
- \r
- private void saveTemplateTableContent() {\r
- File path = DemoRecorderUtils.computeLocalFile(DemoRecorderApplication.PREFERENCES_DIRNAME, TEMPLATE_TABLE_CONTENT_FILENAME);\r
- RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();\r
- tableModel.saveTemplateListToFile(path);\r
- }\r
- \r
- private Icon getIcon(String iconString) {\r
- URL url = ClassLoader.getSystemResource("icons/" + iconString);\r
- Icon i = new ImageIcon(url);\r
- return i;\r
- }\r
-\r
-}\r
+package com.nexuiz.demorecorder.ui.swinggui;
+
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.help.HelpBroker;
+import javax.help.HelpSet;
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.UIManager;
+import javax.swing.border.TitledBorder;
+
+import net.miginfocom.swing.MigLayout;
+
+import org.jdesktop.swingx.JXTable;
+
+import com.nexuiz.demorecorder.application.DemoRecorderApplication;
+import com.nexuiz.demorecorder.application.DemoRecorderUtils;
+import com.nexuiz.demorecorder.application.NDRPreferences;
+import com.nexuiz.demorecorder.application.DemoRecorderApplication.Preferences;
+import com.nexuiz.demorecorder.application.jobs.RecordJob;
+import com.nexuiz.demorecorder.application.jobs.RecordJob.State;
+import com.nexuiz.demorecorder.application.plugins.EncoderPlugin;
+import com.nexuiz.demorecorder.ui.DemoRecorderUI;
+import com.nexuiz.demorecorder.ui.swinggui.tablemodels.RecordJobTemplatesTableModel;
+import com.nexuiz.demorecorder.ui.swinggui.tablemodels.RecordJobsTableModel;
+import com.nexuiz.demorecorder.ui.swinggui.utils.ShowErrorDialogExceptionHandler;
+import com.nexuiz.demorecorder.ui.swinggui.utils.XProperties;
+import com.nexuiz.demorecorder.ui.swinggui.utils.XProperties.XTableState;
+
+public class SwingGUI extends JFrame implements WindowListener, DemoRecorderUI {
+
+ private static final long serialVersionUID = -7287303462488231068L;
+ public static final String JOB_TABLE_PREFERENCES_FILENAME = "jobsTable.pref";
+ public static final String TEMPLATE_TABLE_PREFERENCES_FILENAME = "templatesTable.pref";
+ public static final String TEMPLATE_TABLE_CONTENT_FILENAME = "templates.dat";
+
+ private DemoRecorderApplication appLayer;
+ private PreferencesDialog preferencesDialog;
+
+ private JXTable jobsTable = null;
+ private JPopupMenu jobsTablePopupMenu;
+ private ActionListener jobButtonActionListener = new JobButtonActionListener();
+ private MouseListener jobsTableMouseListener = new JobsTableMouseListener();
+
+ private JXTable templatesTable = null;
+ private JPopupMenu templatesTablePopupMenu;
+ private ActionListener templateButtonActionListener = new TemplateButtonActionListener();
+ private MouseListener templatesTableMouseListener = new TemplatesTableMouseListener();
+
+ private ActionListener recordButtonActionListener = new RecordButtonActionListener();
+
+ private static final String LABEL_JOB_CREATE = "Create";
+ private static final String LABEL_JOB_CREATE_FROM_TEMPL = "Create from template";
+ private static final String LABEL_JOB_DELETE = "Delete";
+ private static final String LABEL_JOB_CLEAR = "Clear";
+ private static final String LABEL_JOB_EDIT = "Edit job";
+ private static final String LABEL_JOB_DUPLICATE = "Duplicate job";
+ private static final String LABEL_JOB_APPLYTEMPL = "Apply template";
+ private static final String LABEL_JOB_START = "Start job";
+ private static final String LABEL_JOB_SHOWERROR = "Show error message";
+ private static final String LABEL_JOB_RESET_STATE_WAITING = "Reset job status to 'waiting'";
+ private static final String LABEL_JOB_RESET_STATE_DONE = "Reset job status to 'done'";
+
+ private static final String LABEL_TEMPL_CREATE = "Create";
+ private static final String LABEL_TEMPL_CREATE_FROM_JOB = "Create from job";
+ private static final String LABEL_TEMPL_DELETE = "Delete";
+ private static final String LABEL_TEMPL_CLEAR = "Clear";
+ private static final String LABEL_TEMPL_EDIT = "Edit template";
+ private static final String LABEL_TEMPL_DUPLICATE = "Duplicate template";
+
+ private ActionListener menuButtonActionListener = new MenuButtonActionListener();
+ private JMenuItem fileLoadQueue = new JMenuItem("Load job queue", getIcon("fileopen.png"));
+ private JMenuItem fileSaveQueue = new JMenuItem("Save job queue", getIcon("filesave.png"));
+ private JMenuItem fileLoadTemplates = new JMenuItem("Load templates", getIcon("fileopen.png"));
+ private JMenuItem fileSaveTemplates = new JMenuItem("Save templates", getIcon("filesave.png"));
+ private JMenuItem filePreferences = new JMenuItem("Preferences", getIcon("advanced.png"));
+ private JMenuItem fileExit = new JMenuItem("Exit", getIcon("exit.png"));
+ private JMenuItem helpHelp = new JMenuItem("Show help", getIcon("help.png"));
+ private JMenuItem helpAbout = new JMenuItem("About", getIcon("info.png"));
+ private JFileChooser jobQueueSaveAsFC = new JFileChooser();
+ private JFileChooser templatesSaveAsFC = new JFileChooser();
+
+ private JButton jobs_create = new JButton(LABEL_JOB_CREATE, getIcon("edit_add.png"));
+ private JButton jobs_createFromTempl = new JButton(LABEL_JOB_CREATE_FROM_TEMPL, getIcon("view_right_p.png"));
+ private JButton jobs_delete = new JButton(LABEL_JOB_DELETE, getIcon("editdelete.png"));
+ private JButton jobs_clear = new JButton(LABEL_JOB_CLEAR, getIcon("editclear.png"));
+ private JMenuItem jobs_contextmenu_edit = new JMenuItem(LABEL_JOB_EDIT, getIcon("edit.png"));
+ private JMenuItem jobs_contextmenu_duplicate = new JMenuItem(LABEL_JOB_DUPLICATE, getIcon("editcopy.png"));
+ private JMenuItem jobs_contextmenu_applytempl = new JMenuItem(LABEL_JOB_APPLYTEMPL, getIcon("editpaste.png"));
+ private JMenuItem jobs_contextmenu_delete = new JMenuItem(LABEL_JOB_DELETE, getIcon("editdelete.png"));
+ private JMenuItem jobs_contextmenu_start = new JMenuItem(LABEL_JOB_START, getIcon("player_play.png"));
+ private JMenuItem jobs_contextmenu_showerror = new JMenuItem(LABEL_JOB_SHOWERROR, getIcon("status_unknown.png"));
+ private JMenuItem jobs_contextmenu_resetstate_waiting = new JMenuItem(LABEL_JOB_RESET_STATE_WAITING, getIcon("quick_restart.png"));
+ private JMenuItem jobs_contextmenu_resetstate_done = new JMenuItem(LABEL_JOB_RESET_STATE_DONE, getIcon("quick_restart_blue.png"));
+ private List<JMenuItem> jobs_contextmenu_runPluginMenuItems = new ArrayList<JMenuItem>();
+
+ private JButton templ_create = new JButton(LABEL_TEMPL_CREATE, getIcon("edit_add.png"));
+ private JButton templ_createFromJob = new JButton(LABEL_TEMPL_CREATE_FROM_JOB, getIcon("view_right_p.png"));
+ private JButton templ_delete = new JButton(LABEL_TEMPL_DELETE, getIcon("editdelete.png"));
+ private JButton templ_clear = new JButton(LABEL_TEMPL_CLEAR, getIcon("editclear.png"));
+ private JMenuItem templ_contextmenu_edit = new JMenuItem(LABEL_TEMPL_EDIT, getIcon("edit.png"));
+ private JMenuItem templ_contextmenu_duplicate = new JMenuItem(LABEL_TEMPL_DUPLICATE, getIcon("editcopy.png"));
+ private JMenuItem templ_contextmenu_delete = new JMenuItem(LABEL_TEMPL_DELETE, getIcon("editdelete.png"));
+
+ private static final String PROCESSING_START = "Start processing";
+ private static final String PROCESSING_STOP_NOW = "Stop processing";
+ private static final String PROCESSING_STOP_LATER = "Processing will stop after current job finished";
+ private JButton processing_start = new JButton(PROCESSING_START, getIcon("player_play.png"));
+ private JButton processing_stop = new JButton(PROCESSING_STOP_NOW, getIcon("player_pause.png"));
+
+ private StatusBar statusBar = new StatusBar();
+
+ private static HelpBroker mainHelpBroker = null;
+ private static final String mainHelpSetName = "help/DemoRecorderHelp.hs";
+
+ public SwingGUI(DemoRecorderApplication appLayer) {
+ super("Nexuiz Demo Recorder v0.3");
+ addWindowListener(this);
+
+ this.appLayer = appLayer;
+
+ this.setupLayout();
+ this.setupHelp();
+ this.preferencesDialog = new PreferencesDialog(this, appLayer);
+
+ setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+ // Display the window.
+ pack();
+ setVisible(true);
+ //now that we have the GUI we can set the parent window for the error dialog
+ ShowErrorDialogExceptionHandler.setParentWindow(this);
+ }
+
+ private void setupHelp() {
+ if (mainHelpBroker == null){
+ HelpSet mainHelpSet = null;
+
+ try {
+ URL hsURL = HelpSet.findHelpSet(null, mainHelpSetName);
+ mainHelpSet = new HelpSet(null, hsURL);
+ } catch (Exception e) {
+ DemoRecorderUtils.showNonCriticalErrorDialog("Could not properly create the help", e, true);
+ }
+
+ if (mainHelpSet != null)
+ mainHelpBroker = mainHelpSet.createHelpBroker();
+ }
+ }
+
+ private void setupLayout() {
+ setLayout(new MigLayout("wrap 1,insets 10", "[400:700:,grow,fill]",
+ "[grow,fill][grow,fill][][]"));
+ Container contentPane = getContentPane();
+ setJMenuBar(this.buildMenu());
+
+ this.setupTemplatePanel();
+ this.setupJobPanel();
+ this.setupRecordPanel();
+
+ contentPane.add(statusBar, "south,height 23::");
+ }
+
+ private void setupTemplatePanel() {
+ JPanel templatePanel = new JPanel(new MigLayout("", "[500:500:,grow,fill][170!,fill,grow]", "[grow,fill]"));
+ TitledBorder templatePanelTitle = BorderFactory.createTitledBorder("Templates");
+ templatePanel.setBorder(templatePanelTitle);
+ getContentPane().add(templatePanel);
+
+ this.setupTemplatesTable();
+ this.loadTableStates(this.templatesTable);
+ JScrollPane templateScrollPane = new JScrollPane(templatesTable);
+ templatePanel.add(templateScrollPane);
+
+ this.templ_create.addActionListener(this.templateButtonActionListener);
+ this.templ_createFromJob.addActionListener(this.templateButtonActionListener);
+ this.templ_delete.addActionListener(this.templateButtonActionListener);
+ this.templ_clear.addActionListener(this.templateButtonActionListener);
+
+ this.templ_contextmenu_edit.addActionListener(this.templateButtonActionListener);
+ this.templ_contextmenu_duplicate.addActionListener(this.templateButtonActionListener);
+ this.templ_contextmenu_delete.addActionListener(this.templateButtonActionListener);
+
+ this.configureTableButtons();
+
+ JPanel templateControlButtonPanel = new JPanel(new MigLayout("wrap 1", "fill,grow"));
+ templateControlButtonPanel.add(this.templ_create);
+ templateControlButtonPanel.add(this.templ_createFromJob);
+ templateControlButtonPanel.add(this.templ_delete);
+ templateControlButtonPanel.add(this.templ_clear);
+ templatePanel.add(templateControlButtonPanel);
+ }
+
+ private void setupJobPanel() {
+ JPanel jobPanel = new JPanel(new MigLayout("", "[500:500:,grow,fill][170!,fill,grow]", "[grow,fill]"));
+ TitledBorder jobPanelTitle = BorderFactory.createTitledBorder("Jobs");
+ jobPanel.setBorder(jobPanelTitle);
+ getContentPane().add(jobPanel);
+
+ this.setupJobsTable();
+ this.loadTableStates(this.jobsTable);
+
+ JScrollPane jobScrollPane = new JScrollPane(jobsTable);
+ jobPanel.add(jobScrollPane);
+
+ this.jobs_create.addActionListener(this.jobButtonActionListener);
+ this.jobs_createFromTempl.addActionListener(this.jobButtonActionListener);
+ this.jobs_delete.addActionListener(this.jobButtonActionListener);
+ this.jobs_clear.addActionListener(this.jobButtonActionListener);
+
+ this.jobs_contextmenu_edit.addActionListener(this.jobButtonActionListener);
+ this.jobs_contextmenu_duplicate.addActionListener(this.jobButtonActionListener);
+ this.jobs_contextmenu_applytempl.addActionListener(this.jobButtonActionListener);
+ this.jobs_contextmenu_delete.addActionListener(this.jobButtonActionListener);
+ this.jobs_contextmenu_start.addActionListener(this.jobButtonActionListener);
+ this.jobs_contextmenu_showerror.addActionListener(this.jobButtonActionListener);
+ this.jobs_contextmenu_resetstate_waiting.addActionListener(this.jobButtonActionListener);
+ this.jobs_contextmenu_resetstate_done.addActionListener(this.jobButtonActionListener);
+
+ //initialize button states
+ configureTableButtons();
+
+ JPanel jobControlButtonPanel = new JPanel(new MigLayout("wrap 1", "fill,grow"));
+ jobControlButtonPanel.add(this.jobs_create);
+ jobControlButtonPanel.add(this.jobs_createFromTempl);
+ jobControlButtonPanel.add(this.jobs_delete);
+ jobControlButtonPanel.add(this.jobs_clear);
+ jobPanel.add(jobControlButtonPanel);
+ }
+
+ private void setupJobsTable() {
+ RecordJobsTableModel tableModel = new RecordJobsTableModel(this.appLayer);
+ jobsTable = new JXTable(tableModel);
+ jobsTable.setColumnControlVisible(true);
+ jobsTable.setPreferredScrollableViewportSize(new Dimension(400, 100));
+ jobsTable.addMouseListener(this.jobsTableMouseListener);
+ }
+
+ private void setupTemplatesTable() {
+ RecordJobTemplatesTableModel tableModel = new RecordJobTemplatesTableModel();
+ templatesTable = new JXTable(tableModel);
+ templatesTable.setColumnControlVisible(true);
+ templatesTable.setPreferredScrollableViewportSize(new Dimension(400, 100));
+ templatesTable.addMouseListener(this.templatesTableMouseListener);
+ }
+
+ private void setupRecordPanel() {
+ JPanel recButtonPanel = new JPanel(new MigLayout());
+ recButtonPanel.add(processing_start);
+ recButtonPanel.add(processing_stop);
+ processing_stop.setEnabled(false);
+ processing_start.addActionListener(recordButtonActionListener);
+ processing_stop.addActionListener(recordButtonActionListener);
+ getContentPane().add(recButtonPanel);
+ }
+
+ public static void setSystemLAF() {
+ try {
+ // Set System L&F
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception e) {
+ }
+ }
+
+ public void RecordJobPropertiesChange(RecordJob job) {
+ RecordJobsTableModel jobsTableModel = (RecordJobsTableModel) this.jobsTable.getModel();
+ List<RecordJob> recordJobs = jobsTableModel.getRecordJobs();
+ int jobIndex = recordJobs.indexOf(job);
+ if (jobIndex == -1) {
+ //new job
+ recordJobs.add(job);
+ //add job at the end of the table:
+ int position = jobsTableModel.getRowCount() - 1;
+ jobsTableModel.fireTableRowsInserted(position, position);
+ } else {
+ //job already existed
+ jobIndex = this.jobsTable.convertRowIndexToView(jobIndex); //convert due to possible view sorting
+ jobsTableModel.fireTableRowsUpdated(jobIndex, jobIndex);
+ }
+ }
+
+ public void recordingFinished() {
+ JOptionPane.showMessageDialog(SwingGUI.this, "Finished recording all jobs", "Recording done", JOptionPane.INFORMATION_MESSAGE);
+ statusBar.showState(false);
+ processing_start.setEnabled(true);
+ processing_stop.setEnabled(false);
+ processing_stop.setText(PROCESSING_STOP_NOW);
+ }
+
+ private JMenuBar buildMenu() {
+ JMenuBar menuBar = new JMenuBar();
+
+ JMenu fileMenu = new JMenu("File");
+ fileMenu.add(fileLoadQueue);
+ fileMenu.add(fileSaveQueue);
+ fileMenu.add(fileLoadTemplates);
+ fileMenu.add(fileSaveTemplates);
+ fileMenu.add(filePreferences);
+ fileMenu.add(fileExit);
+ menuBar.add(fileMenu);
+
+ fileLoadQueue.addActionListener(menuButtonActionListener);
+ fileSaveQueue.addActionListener(menuButtonActionListener);
+ fileLoadTemplates.addActionListener(menuButtonActionListener);
+ fileSaveTemplates.addActionListener(menuButtonActionListener);
+ filePreferences.addActionListener(menuButtonActionListener);
+ fileExit.addActionListener(menuButtonActionListener);
+
+ JMenu helpMenu = new JMenu("Help");
+ helpMenu.add(helpHelp);
+ helpMenu.add(helpAbout);
+ menuBar.add(helpMenu);
+
+ helpHelp.addActionListener(menuButtonActionListener);
+ helpAbout.addActionListener(menuButtonActionListener);
+
+ this.setupEncoderPluginButtons();
+
+ this.jobsTablePopupMenu = new JPopupMenu();
+ this.jobsTablePopupMenu.add(jobs_contextmenu_edit);
+ this.jobsTablePopupMenu.add(jobs_contextmenu_duplicate);
+ this.jobsTablePopupMenu.add(jobs_contextmenu_applytempl);
+ this.jobsTablePopupMenu.add(jobs_contextmenu_delete);
+ this.jobsTablePopupMenu.add(jobs_contextmenu_start);
+ //add JMenus for plugins
+ for (JMenuItem menuItem : jobs_contextmenu_runPluginMenuItems) {
+ this.jobsTablePopupMenu.add(menuItem);
+ }
+ this.jobsTablePopupMenu.add(jobs_contextmenu_showerror);
+ this.jobsTablePopupMenu.add(jobs_contextmenu_resetstate_waiting);
+ this.jobsTablePopupMenu.add(jobs_contextmenu_resetstate_done);
+
+
+
+
+ this.templatesTablePopupMenu = new JPopupMenu();
+ this.templatesTablePopupMenu.add(templ_contextmenu_edit);
+ this.templatesTablePopupMenu.add(templ_contextmenu_duplicate);
+ this.templatesTablePopupMenu.add(templ_contextmenu_delete);
+
+ return menuBar;
+ }
+
+ private void setupEncoderPluginButtons() {
+ for (EncoderPlugin plugin : appLayer.getEncoderPlugins()) {
+ JMenuItem pluginMenuItem = new JMenuItem("Just run " + plugin.getName() + " plugin", getIcon("package.png"));
+ pluginMenuItem.addActionListener(jobButtonActionListener);
+ this.jobs_contextmenu_runPluginMenuItems.add(pluginMenuItem);
+ }
+ }
+
+ private void saveTableStates(JXTable table) {
+ String fileName;
+ if (table == jobsTable) {
+ fileName = JOB_TABLE_PREFERENCES_FILENAME;
+ } else {
+ fileName = TEMPLATE_TABLE_PREFERENCES_FILENAME;
+ }
+ String exceptionMessage = "An error occurred while trying to save the table state file " + fileName;
+
+ XProperties.XTableProperty t = new XProperties.XTableProperty();
+ XTableState tableState;
+ try {
+ tableState = (XTableState) t.getSessionState(table);
+ } catch (Exception e) { //most likely ClassCastException
+ DemoRecorderUtils.showNonCriticalErrorDialog(exceptionMessage, e, true);
+ return;
+ }
+
+ File tableStateFile = DemoRecorderUtils.computeLocalFile(DemoRecorderApplication.PREFERENCES_DIRNAME, fileName);
+ DemoRecorderUtils.attemptFileCreation(tableStateFile);
+
+ try {
+ FileOutputStream fout = new FileOutputStream(tableStateFile);
+ ObjectOutputStream oos = new ObjectOutputStream(fout);
+ oos.writeObject(tableState);
+ oos.close();
+ } catch (Exception e) {
+ DemoRecorderUtils.showNonCriticalErrorDialog(exceptionMessage, e, true);
+ }
+ }
+
+ private void loadTableStates(JXTable table) {
+ String fileName;
+ if (table == jobsTable) {
+ fileName = JOB_TABLE_PREFERENCES_FILENAME;
+ } else {
+ fileName = TEMPLATE_TABLE_PREFERENCES_FILENAME;
+ }
+
+ XProperties.XTableProperty t = new XProperties.XTableProperty();
+
+ File tableStateFile = DemoRecorderUtils.computeLocalFile(DemoRecorderApplication.PREFERENCES_DIRNAME, fileName);
+
+ XTableState tableState;
+
+ try {
+ FileInputStream fin = new FileInputStream(tableStateFile);
+ ObjectInputStream ois = new ObjectInputStream(fin);
+ tableState = (XTableState) ois.readObject();
+ t.setSessionState(table, tableState);
+ } catch (Exception e) {
+ //manually hide columns
+ if (table == jobsTable) {
+ //re-create table to be sure
+ this.setupJobsTable();
+ //manually hide some columns
+ jobsTable.getColumnExt(RecordJobsTableModel.EXECUTE_AFTER_CAP).setVisible(false);
+ jobsTable.getColumnExt(RecordJobsTableModel.EXECUTE_BEFORE_CAP).setVisible(false);
+ jobsTable.getColumnExt(RecordJobsTableModel.VIDEO_DESTINATION_PATH).setVisible(false);
+ jobsTable.getColumnExt(RecordJobsTableModel.DPVIDEO_PATH).setVisible(false);
+ jobsTable.getColumnExt(RecordJobsTableModel.RELATIVE_DEMO_PATH).setVisible(false);
+ jobsTable.getColumnExt(RecordJobsTableModel.ENGINE_PARAMETERS).setVisible(false);
+ jobsTable.getColumnExt(RecordJobsTableModel.ENGINE_PATH).setVisible(false);
+ } else {
+ //re-create table to be sure
+ this.setupTemplatesTable();
+ //manually hide some columns
+ templatesTable.getColumnExt(RecordJobTemplatesTableModel.EXECUTE_AFTER_CAP).setVisible(false);
+ templatesTable.getColumnExt(RecordJobTemplatesTableModel.EXECUTE_BEFORE_CAP).setVisible(false);
+ templatesTable.getColumnExt(RecordJobTemplatesTableModel.VIDEO_DESTINATION_PATH).setVisible(false);
+ templatesTable.getColumnExt(RecordJobTemplatesTableModel.DPVIDEO_PATH).setVisible(false);
+ templatesTable.getColumnExt(RecordJobTemplatesTableModel.RELATIVE_DEMO_PATH).setVisible(false);
+ templatesTable.getColumnExt(RecordJobTemplatesTableModel.DEMO_FILE_PATH).setVisible(false);
+ templatesTable.getColumnExt(RecordJobTemplatesTableModel.ENGINE_PARAMETERS).setVisible(false);
+ templatesTable.getColumnExt(RecordJobTemplatesTableModel.ENGINE_PATH).setVisible(false);
+ templatesTable.getColumnExt(RecordJobTemplatesTableModel.JOB_NAME).setVisible(false);
+ }
+ }
+ }
+
+ private class MenuButtonActionListener implements ActionListener {
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == fileLoadQueue) {
+ int result = jobQueueSaveAsFC.showOpenDialog(SwingGUI.this);
+ if (result == JFileChooser.APPROVE_OPTION) {
+ File selectedFile = jobQueueSaveAsFC.getSelectedFile();
+ if (selectedFile.isFile()) {
+ RecordJobsTableModel tableModel = (RecordJobsTableModel) jobsTable.getModel();
+ tableModel.loadNewJobQueue(SwingGUI.this, selectedFile, jobsTable);
+ configureTableButtons();
+ }
+ }
+
+ } else if (e.getSource() == fileSaveQueue) {
+ int result = jobQueueSaveAsFC.showSaveDialog(SwingGUI.this);
+ if (result == JFileChooser.APPROVE_OPTION) {
+ File selectedFile = jobQueueSaveAsFC.getSelectedFile();
+ if (!DemoRecorderUtils.getFileExtension(selectedFile).equals("queue")) {
+ //if file is not a .queue file, make it one
+ selectedFile = new File(selectedFile.getAbsoluteFile() + ".queue");
+ }
+ if (selectedFile.exists()) {
+ int confirm = JOptionPane.showConfirmDialog(SwingGUI.this, "File already exists. Are you sure you want to overwrite it?", "Confirm overwrite", JOptionPane.YES_NO_OPTION);
+ if (confirm == JOptionPane.NO_OPTION) {
+ return;
+ }
+ }
+ appLayer.saveJobQueue(selectedFile);
+ }
+ } else if (e.getSource() == fileLoadTemplates) {
+ int result = templatesSaveAsFC.showOpenDialog(SwingGUI.this);
+ if (result == JFileChooser.APPROVE_OPTION) {
+ File selectedFile = templatesSaveAsFC.getSelectedFile();
+ if (selectedFile.isFile()) {
+ RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();
+ tableModel.loadNewTemplateList(SwingGUI.this, selectedFile, templatesTable);
+ configureTableButtons();
+ }
+ }
+ } else if (e.getSource() == fileSaveTemplates) {
+ int result = templatesSaveAsFC.showSaveDialog(SwingGUI.this);
+ if (result == JFileChooser.APPROVE_OPTION) {
+ File selectedFile = templatesSaveAsFC.getSelectedFile();
+ if (!DemoRecorderUtils.getFileExtension(selectedFile).equals("templ")) {
+ selectedFile = new File(selectedFile.getAbsoluteFile() + ".templ");
+ }
+ if (selectedFile.exists()) {
+ int confirm = JOptionPane.showConfirmDialog(SwingGUI.this, "File already exists. Are you sure you want to overwrite it?", "Confirm overwrite", JOptionPane.YES_NO_OPTION);
+ if (confirm == JOptionPane.NO_OPTION) {
+ return;
+ }
+ }
+ RecordJobTemplatesTableModel model = (RecordJobTemplatesTableModel) templatesTable.getModel();
+ model.saveTemplateListToFile(selectedFile);
+ }
+ } else if (e.getSource() == filePreferences) {
+ preferencesDialog.showDialog();
+ } else if (e.getSource() == fileExit) {
+ shutDown();
+ } else if (e.getSource() == helpHelp) {
+ if (mainHelpBroker != null) {
+ mainHelpBroker.setDisplayed(true);
+ }
+ } else if (e.getSource() == helpAbout) {
+ showAboutBox();
+ }
+ }
+
+ }
+
+ /**
+ * Listens to the clicks on buttons that are in the job panel (next to the jobs table)
+ * or its context menu.
+ */
+ private class JobButtonActionListener implements ActionListener {
+
+ public void actionPerformed(ActionEvent e) {
+ List<RecordJob> selectedJobs = getSelectedRecordJobs(jobsTable);
+ List<RecordJob> selectedTemplates = getSelectedRecordJobs(templatesTable);
+ if (e.getSource() == jobs_create) {
+ JobDialog jobDialog = new JobDialog(SwingGUI.this, appLayer);
+ jobDialog.showDialog();
+ configureTableButtons();
+ }
+ else if (e.getSource() == jobs_createFromTempl) {
+ if (selectedTemplates.size() != 1) {
+ return;
+ }
+ RecordJobTemplate template = (RecordJobTemplate) selectedTemplates.get(0);
+// JobDialog jobDialog = new JobDialog(SwingGUI.this, template, appLayer);
+ JobDialog jobDialog = new JobDialog(SwingGUI.this, template, appLayer, JobDialog.CREATE_JOB_FROM_TEMPLATE);
+ jobDialog.showDialog();
+ configureTableButtons();
+ }
+ else if (e.getSource() == jobs_delete || e.getSource() == jobs_contextmenu_delete) {
+ int result = JOptionPane.showConfirmDialog(SwingGUI.this, "Are you sure you want to delete the selected job(s)?", "Confirm delete", JOptionPane.YES_NO_OPTION);
+ if (result == JOptionPane.YES_OPTION) {
+ deleteSelectedJobs(false);
+ configureTableButtons();
+ }
+ }
+ else if (e.getSource() == jobs_clear) {
+ int result = JOptionPane.showConfirmDialog(SwingGUI.this, "Are you sure you want to clear the job list?", "Confirm clear", JOptionPane.YES_NO_OPTION);
+ if (result == JOptionPane.YES_OPTION) {
+ deleteSelectedJobs(true);
+ configureTableButtons();
+ }
+ } else if (e.getSource() == jobs_contextmenu_edit) {
+ if (selectedJobs.size() == 1) {
+ RecordJob selectedJob = selectedJobs.get(0);
+ JobDialog jobDialog = new JobDialog(SwingGUI.this, selectedJob, appLayer);
+ jobDialog.showDialog();
+ configureTableButtons();
+ }
+ } else if (e.getSource() == jobs_contextmenu_showerror) {
+ if (selectedJobs.size() == 1) {
+ RecordJob selectedJob = selectedJobs.get(0);
+ DemoRecorderUtils.showNonCriticalErrorDialog(selectedJob.getLastException());
+ }
+ } else if (e.getSource() == jobs_contextmenu_resetstate_waiting) {
+ for (RecordJob job : selectedJobs) {
+ job.setState(RecordJob.State.WAITING);
+ }
+ } else if (e.getSource() == jobs_contextmenu_resetstate_done) {
+ for (RecordJob job : selectedJobs) {
+ if (job.getState() == State.ERROR_PLUGIN) {
+ job.setState(RecordJob.State.DONE);
+ }
+ }
+ } else if (e.getSource() == jobs_contextmenu_start) {
+ appLayer.recordSelectedJobs(selectedJobs);
+ if (appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {
+ processing_start.setEnabled(false);
+ processing_stop.setEnabled(true);
+ statusBar.showState(true);
+ }
+ } else if (e.getSource() == jobs_contextmenu_duplicate) {
+ if (selectedJobs.size() > 0) {
+ this.duplicateRecordJobs(selectedJobs);
+ //select all new duplicates in the table automatically
+ jobsTable.setRowSelectionInterval(jobsTable.getRowCount() - selectedJobs.size(), jobsTable.getRowCount() - 1);
+ configureTableButtons();
+ }
+ } else if (e.getSource() == jobs_contextmenu_applytempl) {
+ if (selectedTemplates.size() == 1 && selectedJobs.size() > 0) {
+ RecordJobTemplate template = (RecordJobTemplate) selectedTemplates.get(0);
+ ApplyTemplateDialog applyDialog = new ApplyTemplateDialog(SwingGUI.this, template, selectedJobs);
+ applyDialog.showDialog();
+ }
+ } else if (jobs_contextmenu_runPluginMenuItems.contains(e.getSource())) {
+ int index = jobs_contextmenu_runPluginMenuItems.indexOf(e.getSource());
+ EncoderPlugin selectedPlugin = appLayer.getEncoderPlugins().get(index);
+
+ appLayer.executePluginForSelectedJobs(selectedPlugin, selectedJobs);
+ if (appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {
+ processing_start.setEnabled(false);
+ processing_stop.setEnabled(true);
+ statusBar.showState(true);
+ }
+ }
+ }
+
+ private void duplicateRecordJobs(List<RecordJob> jobs) {
+ String nameSuffix = appLayer.getPreferences().getProperty(NDRPreferences.MAIN_APPLICATION, Preferences.JOB_NAME_APPEND_DUPLICATE);
+ for (RecordJob job : jobs) {
+ RecordJob newJob = appLayer.createRecordJob(
+ job.getJobName() + nameSuffix,
+ job.getEnginePath(),
+ job.getEngineParameters(),
+ job.getDemoFile(),
+ job.getRelativeDemoPath(),
+ job.getDpVideoPath(),
+ job.getVideoDestination(),
+ job.getExecuteBeforeCap(),
+ job.getExecuteAfterCap(),
+ job.getStartSecond(),
+ job.getEndSecond()
+ );
+ newJob.setEncoderPluginSettings(job.getEncoderPluginSettings());
+ }
+ }
+
+ }
+
+ private class TemplateButtonActionListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == templ_create) {
+ RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();
+ JobDialog jobDialog = new JobDialog(SwingGUI.this, tableModel, templatesTable, appLayer);
+ jobDialog.showDialog();
+ configureTableButtons();
+ }
+ else if (e.getSource() == templ_createFromJob) {
+ this.createTemplateFromJob();
+ configureTableButtons();
+ }
+ else if (e.getSource() == templ_delete || e.getSource() == templ_contextmenu_delete) {
+ int result = JOptionPane.showConfirmDialog(SwingGUI.this, "Are you sure you want to delete the selected template(s)?", "Confirm delete", JOptionPane.YES_NO_OPTION);
+ if (result == JOptionPane.YES_OPTION) {
+ deleteSelectedTemplates(false);
+ }
+ configureTableButtons();
+ }
+ else if (e.getSource() == templ_clear) {
+ int result = JOptionPane.showConfirmDialog(SwingGUI.this, "Are you sure you want to clear the template list?", "Confirm clear", JOptionPane.YES_NO_OPTION);
+ if (result == JOptionPane.YES_OPTION) {
+ deleteSelectedTemplates(true);
+ }
+ configureTableButtons();
+ }
+ else if (e.getSource() == templ_contextmenu_edit) {
+ List<RecordJob> selectedTemplates = getSelectedRecordJobs(templatesTable);
+ if (selectedTemplates.size() == 1) {
+ RecordJobTemplate selectedTemplate = (RecordJobTemplate) selectedTemplates.get(0);
+ JobDialog jobDialog = new JobDialog(SwingGUI.this, selectedTemplate, appLayer, JobDialog.EDIT_TEMPLATE);
+ jobDialog.showDialog();
+ configureTableButtons();
+ }
+ }
+ else if (e.getSource() == templ_contextmenu_duplicate) {
+ List<RecordJob> selectedTemplates = getSelectedRecordJobs(templatesTable);
+ if (selectedTemplates.size() > 0) {
+ this.duplicateTemplates(selectedTemplates);
+ //select all new duplicates in the table automatically
+ templatesTable.setRowSelectionInterval(templatesTable.getRowCount() - selectedTemplates.size(), templatesTable.getRowCount() - 1);
+ configureTableButtons();
+ }
+ }
+ }
+
+ private void createTemplateFromJob() {
+ List<RecordJob> selectedJobs = getSelectedRecordJobs(jobsTable);
+ if (selectedJobs.size() == 1) {
+ RecordJob job = selectedJobs.get(0);
+ RecordJobTemplate templ = new RecordJobTemplate(
+ "Generated from job",
+ "Generated from job",
+ job.getJobName(),
+ job.getEnginePath(),
+ job.getEngineParameters(),
+ job.getDemoFile().getParentFile(),
+ job.getRelativeDemoPath(),
+ job.getDpVideoPath(),
+ job.getVideoDestination().getParentFile(),
+ job.getExecuteBeforeCap(),
+ job.getExecuteAfterCap()
+ );
+ templ.setEncoderPluginSettings(job.getEncoderPluginSettings());
+
+ RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();
+ tableModel.addRecordJobTemplate(templ);
+ }
+ }
+
+ private void duplicateTemplates(List<RecordJob> selectedTemplates) {
+ for (RecordJob job : selectedTemplates) {
+ RecordJobTemplate template = (RecordJobTemplate) job;
+ RecordJobTemplate templ = new RecordJobTemplate(
+ template.getName(),
+ template.getSummary(),
+ template.getJobName(),
+ template.getEnginePath(),
+ template.getEngineParameters(),
+ template.getDemoFile(),
+ template.getRelativeDemoPath(),
+ template.getDpVideoPath(),
+ template.getVideoDestination(),
+ template.getExecuteBeforeCap(),
+ template.getExecuteAfterCap()
+ );
+ templ.setEncoderPluginSettings(template.getEncoderPluginSettings());
+
+ RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();
+ tableModel.addRecordJobTemplate(templ);
+ }
+ }
+ }
+
+ private class RecordButtonActionListener implements ActionListener {
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == processing_start) {
+ appLayer.startRecording();
+ if (appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {
+ processing_start.setEnabled(false);
+ processing_stop.setEnabled(true);
+ statusBar.showState(true);
+ }
+ } else if (e.getSource() == processing_stop) {
+ if (appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {
+ appLayer.stopRecording();
+ processing_stop.setEnabled(false);
+ processing_stop.setText(PROCESSING_STOP_LATER);
+ }
+ }
+ }
+ }
+
+ private void deleteSelectedJobs(boolean deleteAllJobs) {
+ RecordJobsTableModel tableModel = (RecordJobsTableModel) jobsTable.getModel();
+ if (deleteAllJobs) {
+ int rowCount = jobsTable.getRowCount();
+ for (int i = rowCount - 1; i >= 0; i--) {
+ int modelRowIndex = jobsTable.convertRowIndexToModel(i);
+ tableModel.deleteRecordJob(modelRowIndex, i);
+ }
+ } else {
+ int[] selectedRows = jobsTable.getSelectedRows();
+ for (int i = selectedRows.length - 1; i >= 0; i--) {
+ int modelRowIndex = jobsTable.convertRowIndexToModel(selectedRows[i]);
+ tableModel.deleteRecordJob(modelRowIndex, selectedRows[i]);
+ }
+ }
+ }
+
+ private void deleteSelectedTemplates(boolean deleteAllTemplates) {
+ RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();
+ if (deleteAllTemplates) {
+ int rowCount = templatesTable.getRowCount();
+ for (int i = rowCount - 1; i >= 0; i--) {
+ int modelRowIndex = templatesTable.convertRowIndexToModel(i);
+ tableModel.deleteRecordJobTemplate(modelRowIndex, i);
+ }
+ } else {
+ int[] selectedRows = templatesTable.getSelectedRows();
+ for (int i = selectedRows.length - 1; i >= 0; i--) {
+ int modelRowIndex = templatesTable.convertRowIndexToModel(selectedRows[i]);
+ tableModel.deleteRecordJobTemplate(modelRowIndex, selectedRows[i]);
+ }
+ }
+ //update the button state of buttons dealing with jobs
+ this.configureTableButtons();
+ }
+
+ /**
+ * Iterates through all RecordJob objects (or just the selected ones) and returns true
+ * if at least one of them has one or more has the given state(s).
+ * @param state
+ * @param justSelectedJobs
+ * @return
+ */
+ private boolean checkJobStates(RecordJob.State[] state, boolean justSelectedJobs) {
+ boolean foundState = false;
+ List<RecordJob> jobsToLookAt = null;
+ if (!justSelectedJobs) {
+ jobsToLookAt = this.appLayer.getRecordJobs();
+ } else {
+ jobsToLookAt = getSelectedRecordJobs(jobsTable);
+ }
+
+ for (RecordJob currentJob : jobsToLookAt) {
+ for (int i = 0; i < state.length; i++) {
+ if (currentJob.getState() == state[i]) {
+ foundState = true;
+ break;
+ }
+ }
+ }
+ return foundState;
+ }
+
+ /**
+ * Returns the list of selected RecordJobs or RecordJobTemplates.
+ * @param table jobsTable or templatesTable
+ * @return list of selected RecordJobs or RecordJobTemplates
+ */
+ private List<RecordJob> getSelectedRecordJobs(JXTable table) {
+ List<RecordJob> list = new ArrayList<RecordJob>();
+ if (table.getSelectedRowCount() > 0) {
+ int[] selectedRows = table.getSelectedRows();
+ for (int i = 0; i < selectedRows.length; i++) {
+ int modelRowIndex = table.convertRowIndexToModel(selectedRows[i]);
+ if (table == jobsTable) {
+ RecordJobsTableModel tableModel = (RecordJobsTableModel) table.getModel();
+ RecordJob job = tableModel.getRecordJob(modelRowIndex);
+ if (job != null) {
+ list.add(job);
+ }
+ } else {
+ RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) table.getModel();
+ RecordJobTemplate template = tableModel.getRecordJobTemplate(modelRowIndex);
+ if (template != null) {
+ list.add(template);
+ }
+ }
+ }
+ }
+
+ return list;
+ }
+
+ private void configureTableButtons() {
+ if (jobsTable != null) {
+ if (jobsTable.getRowCount() == 0) {
+ jobs_clear.setEnabled(false);
+ jobs_delete.setEnabled(false);
+ } else {
+ jobs_clear.setEnabled(true);
+ jobs_delete.setEnabled(true);
+ if (jobsTable.getSelectedRowCount() == 0) {
+ jobs_delete.setEnabled(false);
+ } else {
+ //go through all elements and check for attributes PROCESSING
+ RecordJob.State[] lookForState = {RecordJob.State.PROCESSING};
+ boolean foundState = checkJobStates(lookForState, false);
+ if (foundState) {
+ //we have to disable the clear and delete button
+ jobs_delete.setEnabled(false);
+ }
+ }
+ }
+ if (templatesTable.getSelectedRowCount() == 1) {
+ jobs_createFromTempl.setEnabled(true);
+ } else {
+ jobs_createFromTempl.setEnabled(false);
+ }
+ }
+
+ if (templatesTable != null) {
+ templ_createFromJob.setEnabled(false);
+ templ_delete.setEnabled(false);
+ templ_clear.setEnabled(false);
+
+ if (jobsTable != null && jobsTable.getSelectedRowCount() == 1) {
+ templ_createFromJob.setEnabled(true);
+ }
+
+ if (templatesTable.getSelectedRowCount() > 0) {
+ templ_delete.setEnabled(true);
+ }
+
+ if (templatesTable.getRowCount() > 0) {
+ templ_clear.setEnabled(true);
+ }
+ }
+ }
+
+ private class JobsTableMouseListener implements MouseListener {
+
+ public void mouseClicked(MouseEvent e) {
+ if (e != null && e.getClickCount() == 2) {
+ List<RecordJob> selectedJobs = getSelectedRecordJobs(jobsTable);
+ if (selectedJobs.size() == 1) {
+ RecordJob selectedJob = selectedJobs.get(0);
+ if (selectedJob.getState() != RecordJob.State.PROCESSING) {
+ JobDialog jobDialog = new JobDialog(SwingGUI.this, selectedJob, appLayer);
+ jobDialog.showDialog();
+ }
+ }
+ } else {
+ configureTableButtons();
+ }
+ }
+
+ public void mouseEntered(MouseEvent e) {}
+
+ public void mouseExited(MouseEvent e) {}
+
+ public void mousePressed(MouseEvent e) {
+ this.showPopupMenu(e);
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ this.showPopupMenu(e);
+ }
+
+ private void showPopupMenu(MouseEvent e) {
+ if (e.isPopupTrigger()) {
+ JTable table = (JTable)(e.getSource());
+ Point p = e.getPoint();
+ int row = table.rowAtPoint(p);
+ int[] selectedRows = table.getSelectedRows();
+ //figure out whether we have to reselect the current row under the pointer,
+ //which is only the case if the already selected rows don't include the one under
+ //the pointer yet
+ boolean reSelect = true;
+ for (int i = 0; i < selectedRows.length; i++) {
+ if (row == selectedRows[i]) {
+ reSelect = false;
+ break;
+ }
+ }
+
+ if (row != -1 && reSelect) {
+ table.setRowSelectionInterval(row, row);
+ }
+
+ this.configurePopupMenu();
+ configureTableButtons();
+ jobsTablePopupMenu.show(e.getComponent(), e.getX(), e.getY());
+ }
+ }
+
+ private void configurePopupMenu() {
+ //Disable all buttons first
+ jobs_contextmenu_edit.setEnabled(false);
+ jobs_contextmenu_duplicate.setEnabled(false);
+ jobs_contextmenu_applytempl.setEnabled(false);
+ jobs_contextmenu_delete.setEnabled(false);
+ jobs_contextmenu_resetstate_waiting.setEnabled(false);
+ jobs_contextmenu_resetstate_done.setEnabled(false);
+ jobs_contextmenu_showerror.setEnabled(false);
+ jobs_contextmenu_start.setEnabled(false);
+ for (JMenuItem pluginItem : jobs_contextmenu_runPluginMenuItems) {
+ pluginItem.setEnabled(false);
+ }
+
+ //edit, duplicate, and show error buttons
+ if (jobsTable.getSelectedRowCount() == 1) {
+ jobs_contextmenu_edit.setEnabled(true);
+
+ //Show error button
+ List<RecordJob> selectedJobs = getSelectedRecordJobs(jobsTable);
+ RecordJob selectedJob = selectedJobs.get(0);
+ if (selectedJob.getState() == RecordJob.State.ERROR || selectedJob.getState() == RecordJob.State.ERROR_PLUGIN) {
+ jobs_contextmenu_showerror.setEnabled(true);
+ }
+ }
+
+ if (jobsTable.getSelectedRowCount() > 0) {
+ jobs_contextmenu_duplicate.setEnabled(true);
+ //Delete button
+ RecordJob.State[] states = {RecordJob.State.PROCESSING};
+ if (!checkJobStates(states, false)) {
+ //none of the jobs is processing
+ jobs_contextmenu_delete.setEnabled(true);
+ jobs_contextmenu_resetstate_waiting.setEnabled(true);
+
+ if (templatesTable.getSelectedRowCount() == 1) {
+ jobs_contextmenu_applytempl.setEnabled(true);
+ }
+ }
+
+ //Start button
+ RecordJob.State[] states2 = {RecordJob.State.ERROR, RecordJob.State.DONE, RecordJob.State.PROCESSING, RecordJob.State.ERROR_PLUGIN};
+ if (!checkJobStates(states2, true)) {
+ //only enable start if none of the selected jobs as any of the States above
+ //as the only job State that is not listed is "waiting", we only enable the button if all jobs are waiting
+ jobs_contextmenu_start.setEnabled(true);
+ }
+
+ //reset to 'done' button
+ RecordJob.State[] states3 = {RecordJob.State.ERROR, RecordJob.State.WAITING, RecordJob.State.PROCESSING};
+ if (!checkJobStates(states3, true)) {
+ //only enable the "reset to done" button when processes have the state DONE or ERROR_PLUGIN
+ jobs_contextmenu_resetstate_done.setEnabled(true);
+ }
+
+ //plugin buttons, enable only when state of the job is DONE
+ RecordJob.State[] states4 = {RecordJob.State.ERROR, RecordJob.State.WAITING, RecordJob.State.PROCESSING, RecordJob.State.ERROR_PLUGIN};
+ if (!checkJobStates(states4, true)) {
+ int counter = 0;
+ for (JMenuItem pluginItem : jobs_contextmenu_runPluginMenuItems) {
+ if (appLayer.getEncoderPlugins().get(counter).isEnabled()) {
+ pluginItem.setEnabled(true);
+ }
+ counter++;
+ }
+ }
+ }
+ }
+
+ }
+
+ private class TemplatesTableMouseListener implements MouseListener {
+
+ public void mouseClicked(MouseEvent e) {
+ if (e != null && e.getClickCount() == 2) {
+ List<RecordJob> selectedJobs = getSelectedRecordJobs(templatesTable);
+ if (selectedJobs.size() == 1) {
+ RecordJobTemplate selectedJob = (RecordJobTemplate) selectedJobs.get(0);
+ JobDialog jobDialog = new JobDialog(SwingGUI.this, selectedJob, appLayer, JobDialog.EDIT_TEMPLATE);
+ jobDialog.showDialog();
+ configureTableButtons();
+ }
+ } else {
+ configureTableButtons();
+ }
+ }
+
+ public void mouseEntered(MouseEvent e) {}
+
+ public void mouseExited(MouseEvent e) {}
+
+ public void mousePressed(MouseEvent e) {
+ this.showPopupMenu(e);
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ this.showPopupMenu(e);
+ }
+
+ private void showPopupMenu(MouseEvent e) {
+ if (e.isPopupTrigger()) {
+ JTable table = (JTable)(e.getSource());
+ Point p = e.getPoint();
+ int row = table.rowAtPoint(p);
+ int[] selectedRows = table.getSelectedRows();
+ //figure out whether we have to reselect the current row under the pointer,
+ //which is only the case if the already selected rows don't include the one under
+ //the pointer yet
+ boolean reSelect = true;
+ for (int i = 0; i < selectedRows.length; i++) {
+ if (row == selectedRows[i]) {
+ reSelect = false;
+ break;
+ }
+ }
+
+ if (row != -1 && reSelect) {
+ table.setRowSelectionInterval(row, row);
+ }
+
+ this.configurePopupMenu();
+ configureTableButtons();
+ templatesTablePopupMenu.show(e.getComponent(), e.getX(), e.getY());
+ }
+ }
+
+ private void configurePopupMenu() {
+ //Various buttons
+ templ_contextmenu_edit.setEnabled(false);
+ templ_contextmenu_duplicate.setEnabled(false);
+ templ_contextmenu_delete.setEnabled(false);
+
+ //Edit button
+ if (templatesTable.getSelectedRowCount() == 1) {
+ templ_contextmenu_edit.setEnabled(true);
+ }
+
+ //Delete and duplicate button
+ if (templatesTable.getSelectedRowCount() > 0) {
+ templ_contextmenu_delete.setEnabled(true);
+ templ_contextmenu_duplicate.setEnabled(true);
+ }
+ }
+ }
+
+ private void showAboutBox() {
+ try {
+ InputStream inStream = ClassLoader.getSystemResourceAsStream("about.html");
+ StringBuffer out = new StringBuffer();
+ byte[] b = new byte[4096];
+ for (int n; (n = inStream.read(b)) != -1;) {
+ out.append(new String(b, 0, n));
+ }
+ String htmlString = out.toString();
+ htmlString = htmlString.replaceAll("[\\r\\n]", "");
+ JOptionPane.showMessageDialog(this, htmlString, "About", JOptionPane.PLAIN_MESSAGE);
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ public void windowActivated(WindowEvent e) {}
+ public void windowClosed(WindowEvent e) {}
+ public void windowDeactivated(WindowEvent e) {}
+ public void windowDeiconified(WindowEvent e) {}
+ public void windowIconified(WindowEvent e) {}
+ public void windowOpened(WindowEvent e) {}
+
+ public void windowClosing(WindowEvent e) {
+ this.shutDown();
+ }
+
+ private void shutDown() {
+ if (this.appLayer.getState() == DemoRecorderApplication.STATE_WORKING) {
+ int result = JOptionPane.showConfirmDialog(this, "There are still jobs being recorded. Are you sure you want to exit?", "Confirm close", JOptionPane.YES_NO_OPTION);
+ if (result == JOptionPane.NO_OPTION) {
+ return;
+ }
+ }
+ saveTableStates(jobsTable);
+ saveTableStates(templatesTable);
+ saveTemplateTableContent();
+ this.appLayer.shutDown();
+ this.dispose();
+ System.exit(0);
+ }
+
+ private void saveTemplateTableContent() {
+ File path = DemoRecorderUtils.computeLocalFile(DemoRecorderApplication.PREFERENCES_DIRNAME, TEMPLATE_TABLE_CONTENT_FILENAME);
+ RecordJobTemplatesTableModel tableModel = (RecordJobTemplatesTableModel) templatesTable.getModel();
+ tableModel.saveTemplateListToFile(path);
+ }
+
+ private Icon getIcon(String iconString) {
+ URL url = ClassLoader.getSystemResource("icons/" + iconString);
+ Icon i = new ImageIcon(url);
+ return i;
+ }
+
+}