]> git.xonotic.org Git - xonotic/xonotic.git/blobdiff - misc/tools/NexuizDemoRecorder/main/src/main/java/com/nexuiz/demorecorder/ui/swinggui/JobDialog.java
fix lots of CRLFs
[xonotic/xonotic.git] / misc / tools / NexuizDemoRecorder / main / src / main / java / com / nexuiz / demorecorder / ui / swinggui / JobDialog.java
index adb0f99dcd35c74fa2149c9f56e6d391b1cf8d4a..980695129b44e87a949efda7484b6fabb4d4c96e 100644 (file)
-package com.nexuiz.demorecorder.ui.swinggui;\r
-\r
-import java.awt.Dimension;\r
-import java.awt.Frame;\r
-import java.awt.Toolkit;\r
-import java.awt.event.ActionEvent;\r
-import java.awt.event.ActionListener;\r
-import java.io.File;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-import java.util.Properties;\r
-import java.util.Set;\r
-\r
-import javax.swing.JButton;\r
-import javax.swing.JCheckBox;\r
-import javax.swing.JComponent;\r
-import javax.swing.JDialog;\r
-import javax.swing.JFileChooser;\r
-import javax.swing.JLabel;\r
-import javax.swing.JPanel;\r
-import javax.swing.JScrollPane;\r
-import javax.swing.JTextArea;\r
-import javax.swing.JTextField;\r
-import javax.swing.ScrollPaneConstants;\r
-import javax.swing.border.EmptyBorder;\r
-import javax.swing.filechooser.FileFilter;\r
-\r
-import net.miginfocom.swing.MigLayout;\r
-\r
-import org.jdesktop.swingx.JXTable;\r
-import org.jdesktop.swingx.JXTitledSeparator;\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.jobs.RecordJob;\r
-import com.nexuiz.demorecorder.application.plugins.EncoderPlugin;\r
-import com.nexuiz.demorecorder.ui.swinggui.tablemodels.RecordJobTemplatesTableModel;\r
-import com.nexuiz.demorecorder.ui.swinggui.utils.SwingGUIUtils;\r
-\r
-/**\r
- * Shows the dialog that allows to create a new job, create one from a template\r
- * or edit an existing job.\r
- */\r
-\r
-public class JobDialog extends JDialog implements ActionListener {\r
-       private static final long serialVersionUID = 6926246716804560522L;\r
-       public static final int CREATE_NEW_JOB = 0;\r
-       public static final int EDIT_JOB = 1;\r
-       public static final int CREATE_NEW_TEMPLATE = 2;\r
-       public static final int EDIT_TEMPLATE = 3;\r
-       public static final int CREATE_JOB_FROM_TEMPLATE = 4;\r
-\r
-       private DemoRecorderApplication appLayer;\r
-       private RecordJobTemplatesTableModel tableModel;\r
-//     private JXTable templatesTable;\r
-       private Frame parentFrame;\r
-       private int dialogType;\r
-       private RecordJob job = null;\r
-       private JPanel inputPanel;\r
-       private JPanel buttonPanel;\r
-\r
-       private JTextField templateNameField;\r
-       private JTextField templateSummaryField;\r
-       private JTextField enginePathField;\r
-       private JButton enginePathChooserButton;\r
-       private JTextField engineParameterField;\r
-       private JTextField dpVideoDirField;\r
-       private JButton dpVideoDirChooserButton;\r
-       private JTextField relativeDemoPathField;\r
-       private JTextField jobNameField;\r
-       private JTextField demoFileField;\r
-       private JButton demoFileChooserButton;\r
-       private JTextField startSecondField;\r
-       private JTextField endSecondField;\r
-       private JTextArea execBeforeField;\r
-       private JTextArea execAfterField;\r
-       private JTextField videoDestinationField;\r
-       private JButton videoDestinationChooserButton;\r
-       \r
-       private JButton createButton;\r
-       private JButton cancelButton;\r
-       \r
-       //file choosers\r
-       private JFileChooser enginePathFC;\r
-       private JFileChooser dpVideoDirFC;\r
-       private JFileChooser demoFileFC;\r
-       private JFileChooser videoDestinationFC;\r
-       \r
-       private FileFilter userDirFilter = new NexuizUserDirFilter();\r
-       \r
-       private Map<String, JComponent> pluginDialogSettings = new HashMap<String, JComponent>();\r
-\r
-       /**\r
-        * Constructor to create a dialog when creating a new job.\r
-        * @param owner\r
-        * @param appLayer\r
-        */\r
-       public JobDialog(Frame owner, DemoRecorderApplication appLayer) {\r
-               super(owner, true);\r
-               this.parentFrame = owner;\r
-               this.dialogType = CREATE_NEW_JOB;\r
-               this.appLayer = appLayer;\r
-               setDefaultCloseOperation(DISPOSE_ON_CLOSE);\r
-\r
-               setTitle("Create new job");\r
-\r
-               this.setupLayout();\r
-       }\r
-       \r
-       /**\r
-        * Constructor to create a dialog when creating a new template.\r
-        * @param owner\r
-        * @param dialogType\r
-        * @param appLayer\r
-        */\r
-       public JobDialog(Frame owner, RecordJobTemplatesTableModel tableModel, JXTable templatesTable, DemoRecorderApplication appLayer) {\r
-               super(owner, true);\r
-               this.parentFrame = owner;\r
-               this.dialogType = CREATE_NEW_TEMPLATE;\r
-               this.tableModel = tableModel;\r
-               this.appLayer = appLayer;\r
-//             this.templatesTable = templatesTable; seems we don't need it\r
-               setDefaultCloseOperation(DISPOSE_ON_CLOSE);\r
-               setTitle("Create new template");\r
-\r
-               this.setupLayout();\r
-       }\r
-       \r
-       /**\r
-        * Constructor to use when creating a new job from a template, or when editing a template.\r
-        * @param owner\r
-        * @param template\r
-        * @param type either CREATE_JOB_FROM_TEMPLATE or EDIT_TEMPLATE\r
-        */\r
-       public JobDialog(Frame owner, RecordJobTemplate template, DemoRecorderApplication appLayer, int type) {\r
-               super(owner, true);\r
-               this.parentFrame = owner;\r
-               \r
-               this.job = template;\r
-               this.appLayer = appLayer;\r
-               setDefaultCloseOperation(DISPOSE_ON_CLOSE);\r
-               \r
-               if (type != CREATE_JOB_FROM_TEMPLATE && type != EDIT_TEMPLATE) {\r
-                       throw new RuntimeException("Illegal paraameter \"type\"");\r
-               }\r
-               \r
-               this.dialogType = type;\r
-               if (type == CREATE_JOB_FROM_TEMPLATE) {\r
-                       setTitle("Create job from template");\r
-               } else {\r
-                       setTitle("Edit template");\r
-               }\r
-\r
-               this.setupLayout();\r
-       }\r
-       \r
-       /**\r
-        * Constructor to create a dialog to be used when editing an existing job.\r
-        * @param owner\r
-        * @param job\r
-        */\r
-       public JobDialog(Frame owner, RecordJob job, DemoRecorderApplication appLayer) {\r
-               super(owner, true);\r
-               this.parentFrame = owner;\r
-               this.dialogType = EDIT_JOB;\r
-               this.appLayer = appLayer;\r
-               setDefaultCloseOperation(DISPOSE_ON_CLOSE);\r
-\r
-               setTitle("Edit job");\r
-               this.job = job;\r
-\r
-               this.setupLayout();\r
-       }\r
-       \r
-       \r
-       \r
-       public void showDialog() {\r
-               this.pack();\r
-               Toolkit t = Toolkit.getDefaultToolkit();\r
-               Dimension screenSize = t.getScreenSize();\r
-               if (getHeight() > screenSize.height) {\r
-                       Dimension newPreferredSize = getPreferredSize();\r
-                       newPreferredSize.height = screenSize.height - 100;\r
-                       setPreferredSize(newPreferredSize);\r
-                       this.pack();\r
-               }\r
-               this.setLocationRelativeTo(this.parentFrame);\r
-               this.setVisible(true);\r
-       }\r
-\r
-       private void setupLayout() {\r
-//             setLayout(new MigLayout("wrap 1", "[grow,fill]", "[]20[]"));\r
-               setLayout(new MigLayout("wrap 1", "[grow,fill]", "[][]"));\r
-               this.setupInputMask();\r
-               this.setupButtonPart();\r
-\r
-       }\r
-\r
-       private void setupInputMask() {\r
-               inputPanel = new JPanel(new MigLayout("insets 0,wrap 3", "[][250::,grow,fill][30::]"));\r
-               JScrollPane inputScrollPane = new JScrollPane(inputPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);\r
-               inputScrollPane.setBorder(new EmptyBorder(0,0,0,0));\r
-               \r
-               JXTitledSeparator environmentHeading = new JXTitledSeparator("Environment settings");\r
-               inputPanel.add(environmentHeading, "span 3,grow");\r
-\r
-               this.setupTemplateNameAndSummary();\r
-               this.setupEnginePath();\r
-               this.setupEngineParameters();\r
-               this.setupDPVideoDir();\r
-               this.setupRelativeDemoPath();\r
-\r
-               JXTitledSeparator jobSettingsHeading = new JXTitledSeparator("Job settings");\r
-               inputPanel.add(jobSettingsHeading, "span 3,grow");\r
-\r
-               this.setupJobName();\r
-               this.setupDemoFile();\r
-               this.setupStartSecond();\r
-               this.setupEndSecond();\r
-               this.setupExecBefore();\r
-               this.setupExecAfter();\r
-               this.setupVideoDestination();\r
-               \r
-               this.setupPluginPreferences();\r
-\r
-               getContentPane().add(inputScrollPane);\r
-       }\r
-       \r
-       private void setupTemplateNameAndSummary() {\r
-               if (this.dialogType != CREATE_NEW_TEMPLATE && this.dialogType != EDIT_TEMPLATE) {\r
-                       return;\r
-               }\r
-               \r
-               //layout stuff\r
-               inputPanel.add(new JLabel("Template name:"));\r
-               templateNameField = new JTextField();\r
-               inputPanel.add(templateNameField, "wrap");\r
-               \r
-               inputPanel.add(new JLabel("Summary:"));\r
-               templateSummaryField = new JTextField();\r
-               inputPanel.add(templateSummaryField, "wrap");\r
-               \r
-               //UI logic stuff\r
-               if (this.dialogType == EDIT_TEMPLATE) {\r
-                       RecordJobTemplate template = (RecordJobTemplate) this.job;\r
-                       templateNameField.setText(template.getName());\r
-                       templateSummaryField.setText(template.getSummary());\r
-               }\r
-       }\r
-       \r
-       private void setupEnginePath() {\r
-               //layout stuff\r
-               inputPanel.add(new JLabel("Engine:"));\r
-               enginePathField = new JTextField();\r
-               enginePathField.setEditable(false);\r
-               inputPanel.add(enginePathField);\r
-               enginePathChooserButton = new FileChooserButton();\r
-               inputPanel.add(enginePathChooserButton);\r
-               \r
-               //UI logic stuff\r
-               this.enginePathFC = createConfiguredFileChooser();\r
-               enginePathChooserButton.addActionListener(this);\r
-               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {\r
-                       this.enginePathFC.setSelectedFile(this.job.getEnginePath());\r
-                       this.enginePathField.setText(this.job.getEnginePath().getAbsolutePath());\r
-               }\r
-       }\r
-       \r
-       private void setupEngineParameters() {\r
-               //layout stuff\r
-               inputPanel.add(new JLabel("Engine parameters:"));\r
-               engineParameterField = new JTextField();\r
-               inputPanel.add(engineParameterField, "wrap");\r
-               \r
-               //UI logic stuff\r
-               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {\r
-                       engineParameterField.setText(this.job.getEngineParameters());\r
-               }\r
-       }\r
-       \r
-       private void setupDPVideoDir() {\r
-               //layout stuff\r
-               inputPanel.add(new JLabel("DPVideo directory:"));\r
-               dpVideoDirField = new JTextField();\r
-               dpVideoDirField.setEditable(false);\r
-               inputPanel.add(dpVideoDirField);\r
-               dpVideoDirChooserButton = new FileChooserButton();\r
-               inputPanel.add(dpVideoDirChooserButton);\r
-               \r
-               //UI logic stuff\r
-               dpVideoDirChooserButton.addActionListener(this);\r
-               this.dpVideoDirFC = createConfiguredFileChooser();\r
-               this.dpVideoDirFC.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\r
-               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {\r
-                       this.dpVideoDirFC.setSelectedFile(this.job.getDpVideoPath());\r
-                       this.dpVideoDirField.setText(this.job.getDpVideoPath().getAbsolutePath());\r
-               }\r
-       }\r
-       \r
-       private void setupRelativeDemoPath() {\r
-               //layout stuff\r
-               inputPanel.add(new JLabel("Relative demo path:"));\r
-               relativeDemoPathField = new JTextField();\r
-               inputPanel.add(relativeDemoPathField, "wrap 20");\r
-               \r
-               //UI logic stuff\r
-               if (this.dialogType == CREATE_NEW_JOB || this.dialogType == CREATE_NEW_TEMPLATE) {\r
-                       relativeDemoPathField.setText("demos");\r
-               }\r
-               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {\r
-                       relativeDemoPathField.setText(this.job.getRelativeDemoPath());\r
-               }\r
-       }\r
-       \r
-       private void setupJobName() {\r
-               inputPanel.add(new JLabel("Job name:"));\r
-               \r
-               jobNameField = new JTextField();\r
-               inputPanel.add(jobNameField, "wrap");\r
-               \r
-               //UI logic stuff\r
-               if (this.dialogType != CREATE_NEW_TEMPLATE && this.dialogType != CREATE_NEW_JOB) {\r
-                       jobNameField.setText(this.job.getJobName());\r
-               }\r
-       }\r
-       \r
-       private void setupDemoFile() {\r
-               String label;\r
-               if (this.dialogType == CREATE_NEW_JOB || this.dialogType == EDIT_JOB || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {\r
-                       label = "Demo file:";\r
-               } else {\r
-                       label = "Demo directory:";\r
-               }\r
-               \r
-               //layout stuff\r
-               inputPanel.add(new JLabel(label));\r
-               demoFileField = new JTextField();\r
-               demoFileField.setEditable(false);\r
-               inputPanel.add(demoFileField);\r
-               demoFileChooserButton = new FileChooserButton();\r
-               inputPanel.add(demoFileChooserButton);\r
-               \r
-               //UI logic stuff\r
-               this.demoFileFC = createConfiguredFileChooser();\r
-               demoFileChooserButton.addActionListener(this);\r
-               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {\r
-                       if (this.dialogType == CREATE_JOB_FROM_TEMPLATE) {\r
-                               this.demoFileFC.setCurrentDirectory(this.job.getDemoFile());\r
-                       } else {\r
-                               this.demoFileFC.setSelectedFile(this.job.getDemoFile());\r
-                       }\r
-                       \r
-                       this.demoFileField.setText(this.job.getDemoFile().getAbsolutePath());\r
-               }\r
-               \r
-               //only specify directories for templates\r
-               if (this.dialogType == CREATE_NEW_TEMPLATE || this.dialogType == EDIT_TEMPLATE) {\r
-                       this.demoFileFC.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\r
-               }\r
-       }\r
-       \r
-       private void setupStartSecond() {\r
-               //only exists for jobs, not for templates\r
-               if (this.dialogType != CREATE_NEW_JOB && this.dialogType != EDIT_JOB && this.dialogType != CREATE_JOB_FROM_TEMPLATE) {\r
-                       return;\r
-               }\r
-               \r
-               //layout stuff\r
-               inputPanel.add(new JLabel("Start second:"));\r
-               startSecondField = new JTextField();\r
-               inputPanel.add(startSecondField, "wrap");\r
-               \r
-               //UI logic stuff\r
-               if (this.dialogType == EDIT_JOB) {\r
-                       startSecondField.setText(String.valueOf( this.job.getStartSecond() ));\r
-               }\r
-       }\r
-       \r
-       private void setupEndSecond() {\r
-               //only exists for jobs, not for templates\r
-               if (this.dialogType != CREATE_NEW_JOB && this.dialogType != EDIT_JOB && this.dialogType != CREATE_JOB_FROM_TEMPLATE) {\r
-                       return;\r
-               }\r
-               \r
-               //layout stuff\r
-               inputPanel.add(new JLabel("End second:"));\r
-               endSecondField = new JTextField();\r
-               inputPanel.add(endSecondField, "wrap");\r
-               \r
-               //UI logic stuff\r
-               if (this.dialogType == EDIT_JOB) {\r
-                       endSecondField.setText(String.valueOf( this.job.getEndSecond() ));\r
-               }\r
-       }\r
-       \r
-       private void setupExecBefore() {\r
-               //layout stuff\r
-               inputPanel.add(new JLabel("Exec before capture:"));\r
-               execBeforeField = new JTextArea(3, 1);\r
-               inputPanel.add(new JScrollPane(execBeforeField), "wrap");\r
-               \r
-               //UI logic stuff\r
-               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {\r
-                       execBeforeField.setText(this.job.getExecuteBeforeCap());\r
-               }\r
-       }\r
-       \r
-       private void setupExecAfter() {\r
-               //layout stuff\r
-               inputPanel.add(new JLabel("Exec after capture:"));\r
-               execAfterField = new JTextArea(3, 1);\r
-               inputPanel.add(new JScrollPane(execAfterField), "wrap");\r
-               \r
-               //UI logic stuff\r
-               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {\r
-                       execAfterField.setText(this.job.getExecuteAfterCap());\r
-               }\r
-       }\r
-       \r
-       private void setupVideoDestination() {\r
-               //layout stuff\r
-               inputPanel.add(new JLabel("Video destination:"));\r
-               videoDestinationField = new JTextField();\r
-               videoDestinationField.setEditable(false);\r
-               inputPanel.add(videoDestinationField);\r
-               videoDestinationChooserButton = new FileChooserButton();\r
-               inputPanel.add(videoDestinationChooserButton, "wrap 20");\r
-               \r
-               //UI logic stuff\r
-               videoDestinationChooserButton.addActionListener(this);\r
-               this.videoDestinationFC = createConfiguredFileChooser();\r
-               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {\r
-                       if (this.dialogType == CREATE_JOB_FROM_TEMPLATE) {\r
-                               this.videoDestinationFC.setCurrentDirectory(this.job.getVideoDestination());\r
-                       } else {\r
-                               this.videoDestinationFC.setSelectedFile(this.job.getVideoDestination());\r
-                       }\r
-                       \r
-                       this.videoDestinationField.setText(this.job.getVideoDestination().getAbsolutePath());\r
-               }\r
-               if (this.dialogType == CREATE_NEW_TEMPLATE || this.dialogType == EDIT_TEMPLATE) {\r
-                       this.videoDestinationFC.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\r
-               }\r
-       }\r
-       \r
-       private void setupPluginPreferences() {\r
-               for (EncoderPlugin plugin : this.appLayer.getEncoderPlugins()) {\r
-                       String pluginName = plugin.getName();\r
-                       //only display settings if the plugin actually has any...\r
-                       Properties jobSpecificDefaultPluginPreferences = plugin.getJobSpecificPreferences();\r
-                       Properties jobPluginPreferences = null;\r
-                       if (this.job != null) {\r
-                               jobPluginPreferences = this.job.getEncoderPluginSettings(plugin);\r
-                       }\r
-                       if (jobSpecificDefaultPluginPreferences.size() > 0 && plugin.isEnabled()) {\r
-                               //add heading\r
-                               JXTitledSeparator pluginHeading = new JXTitledSeparator(pluginName + " plugin settings");\r
-                               inputPanel.add(pluginHeading, "span 3,grow");\r
-                               \r
-                               for (String pluginPreferenceKey : plugin.getJobSpecificPreferencesOrder()) {\r
-                                       String value = jobSpecificDefaultPluginPreferences.getProperty(pluginPreferenceKey);\r
-                                       if (this.job != null) {\r
-                                               if (jobPluginPreferences.containsKey(pluginPreferenceKey)) {\r
-                                                       value = jobPluginPreferences.getProperty(pluginPreferenceKey);\r
-                                               }\r
-                                       }\r
-                                       \r
-                                       this.setupSinglePluginSetting(plugin, pluginPreferenceKey, value);\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-       \r
-       private void setupSinglePluginSetting(EncoderPlugin plugin, String key, String value) {\r
-               inputPanel.add(new JLabel(key + ":"));\r
-               \r
-               if (SwingGUIUtils.isBooleanValue(value)) {\r
-                       JCheckBox checkbox = new JCheckBox();\r
-                       checkbox.setSelected(Boolean.valueOf(value));\r
-                       inputPanel.add(checkbox, "wrap");\r
-                       this.pluginDialogSettings.put(NDRPreferences.getConcatenatedKey(plugin.getName(), key), checkbox);\r
-               } else if (SwingGUIUtils.isFileChooser(value)) {\r
-                       final JFileChooser fc = new JFileChooser();\r
-                       fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);\r
-                       JButton fcButton = new JButton("...");\r
-                       final JTextField filePathField = new JTextField();\r
-                       filePathField.setEditable(false);\r
-                       inputPanel.add(filePathField);\r
-                       fcButton.addActionListener(new ActionListener() {\r
-                               @Override\r
-                               public void actionPerformed(ActionEvent e) {\r
-                                       int returnValue = fc.showOpenDialog(JobDialog.this);\r
-                                       if (returnValue == JFileChooser.APPROVE_OPTION) {\r
-                                               File selectedFile = fc.getSelectedFile();\r
-                                               filePathField.setText(selectedFile.getAbsolutePath());\r
-                                       }\r
-                               }\r
-                       });\r
-                       \r
-                       try {\r
-                               File selectedFile = new File(value);\r
-                               if (selectedFile.exists()) {\r
-                                       fc.setSelectedFile(selectedFile);\r
-                                       filePathField.setText(selectedFile.getAbsolutePath());\r
-                               }\r
-                       } catch (Throwable e) {}\r
-                       this.pluginDialogSettings.put(NDRPreferences.getConcatenatedKey(plugin.getName(), key), fc);\r
-                       inputPanel.add(fcButton);\r
-               } else {\r
-                       //textfield\r
-                       JTextField textField = new JTextField();\r
-                       textField.setText(value);\r
-                       this.pluginDialogSettings.put(NDRPreferences.getConcatenatedKey(plugin.getName(), key), textField);\r
-                       inputPanel.add(textField, "wrap");\r
-               }\r
-       }\r
-\r
-       private void setupButtonPart() {\r
-               String createButtonText;\r
-               if (this.dialogType == CREATE_NEW_JOB || this.dialogType == CREATE_NEW_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {\r
-                       createButtonText = "Create";\r
-               } else {\r
-                       createButtonText = "Save";\r
-               }\r
-               buttonPanel = new JPanel(new MigLayout("insets 0"));\r
-               createButton = new JButton(createButtonText);\r
-               createButton.addActionListener(this);\r
-               cancelButton = new JButton("Cancel");\r
-               cancelButton.addActionListener(this);\r
-               \r
-               buttonPanel.add(createButton);\r
-               buttonPanel.add(cancelButton);\r
-\r
-               getContentPane().add(buttonPanel);\r
-       }\r
-       \r
-       \r
-       public void actionPerformed(ActionEvent e) {\r
-               if (e.getSource() == enginePathChooserButton) {\r
-                       int returnValue = this.enginePathFC.showOpenDialog(this);\r
-                       if (returnValue == JFileChooser.APPROVE_OPTION) {\r
-                               File selectedFile = this.enginePathFC.getSelectedFile();\r
-                               this.enginePathField.setText(selectedFile.getAbsolutePath());\r
-                       }\r
-               } else if (e.getSource() == dpVideoDirChooserButton) {\r
-                       int returnValue = this.dpVideoDirFC.showOpenDialog(this);\r
-                       if (returnValue == JFileChooser.APPROVE_OPTION) {\r
-                               File selectedFile = this.dpVideoDirFC.getSelectedFile();\r
-                               this.dpVideoDirField.setText(selectedFile.getAbsolutePath());\r
-                       }\r
-               } else if (e.getSource() == demoFileChooserButton) {\r
-                       int returnValue = this.demoFileFC.showOpenDialog(this);\r
-                       if (returnValue == JFileChooser.APPROVE_OPTION) {\r
-                               File selectedFile = this.demoFileFC.getSelectedFile();\r
-                               if (this.dialogType == CREATE_NEW_JOB || this.dialogType == EDIT_JOB || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {\r
-                                       this.demoFileField.setText(DemoRecorderUtils.getJustFileNameOfPath(selectedFile));\r
-                               } else {\r
-                                       //template, show full path of directory\r
-                                       this.demoFileField.setText(selectedFile.getAbsolutePath());\r
-                               }\r
-                               \r
-                       }\r
-               } else if (e.getSource() == videoDestinationChooserButton) {\r
-                       int returnValue = this.videoDestinationFC.showSaveDialog(this);\r
-                       if (returnValue == JFileChooser.APPROVE_OPTION) {\r
-                               File selectedFile = this.videoDestinationFC.getSelectedFile();\r
-                               this.videoDestinationField.setText(selectedFile.getAbsolutePath());\r
-                       }\r
-               } else if (e.getSource() == createButton) {\r
-                       switch (this.dialogType) {\r
-                       case CREATE_NEW_JOB:\r
-                       case CREATE_JOB_FROM_TEMPLATE:\r
-                               this.requestNewRecordJob(); break;\r
-                       case CREATE_NEW_TEMPLATE:\r
-                               this.createNewTemplate();\r
-                               break;\r
-                       case EDIT_JOB:\r
-                               this.editJob();\r
-                               break;\r
-                       case EDIT_TEMPLATE:\r
-                               this.editTemplate();\r
-                               break;\r
-                       }\r
-               } else if (e.getSource() == cancelButton) {\r
-                       dispose();\r
-               }\r
-       }\r
-       \r
-       private void requestNewRecordJob() {\r
-               float startSecond, endSecond = -1;\r
-               try {\r
-                       startSecond = Float.valueOf(this.startSecondField.getText());\r
-                       endSecond = Float.valueOf(this.endSecondField.getText());\r
-               } catch (Exception e) {\r
-                       DemoRecorderUtils.showNonCriticalErrorDialog("Make sure that start and end second are floating point numbers", e, true);\r
-                       return;\r
-               }\r
-               \r
-               try {\r
-                       RecordJob j = this.appLayer.createRecordJob(\r
-                               this.jobNameField.getText(),\r
-                               this.enginePathFC.getSelectedFile(),\r
-                               this.engineParameterField.getText(),\r
-                               this.demoFileFC.getSelectedFile(),\r
-                               this.relativeDemoPathField.getText(),\r
-                               this.dpVideoDirFC.getSelectedFile(),\r
-                               this.videoDestinationFC.getSelectedFile(),\r
-                               this.execBeforeField.getText(),\r
-                               this.execAfterField.getText(),\r
-                               startSecond,\r
-                               endSecond\r
-                       );\r
-                       this.saveEncoderPluginSettings(j);\r
-                       dispose();\r
-               } catch (Exception e) {\r
-                       DemoRecorderUtils.showNonCriticalErrorDialog(e);\r
-                       return;\r
-               }\r
-               \r
-       }\r
-       \r
-       private void editJob() {\r
-               float startSecond, endSecond = -1;\r
-               try {\r
-                       startSecond = Float.valueOf(this.startSecondField.getText());\r
-                       endSecond = Float.valueOf(this.endSecondField.getText());\r
-               } catch (Exception e) {\r
-                       DemoRecorderUtils.showNonCriticalErrorDialog("Make sure that start and end second are floating point numbers", e, true);\r
-                       return;\r
-               }\r
-               \r
-               try {\r
-                       this.job.setJobName(this.jobNameField.getText());\r
-                       this.job.setEnginePath(this.enginePathFC.getSelectedFile());\r
-                       this.job.setEngineParameters(this.engineParameterField.getText());\r
-                       this.job.setDemoFile(this.demoFileFC.getSelectedFile());\r
-                       this.job.setRelativeDemoPath(this.relativeDemoPathField.getText());\r
-                       this.job.setDpVideoPath(this.dpVideoDirFC.getSelectedFile());\r
-                       this.job.setVideoDestination(this.videoDestinationFC.getSelectedFile());\r
-                       this.job.setExecuteBeforeCap(this.execBeforeField.getText());\r
-                       this.job.setExecuteAfterCap(this.execAfterField.getText());\r
-                       this.job.setStartSecond(startSecond);\r
-                       this.job.setEndSecond(endSecond);\r
-                       this.saveEncoderPluginSettings(this.job);\r
-                       this.appLayer.fireUserInterfaceUpdate(this.job);\r
-                       dispose();\r
-               } catch (Exception e) {\r
-                       DemoRecorderUtils.showNonCriticalErrorDialog(e);\r
-                       return;\r
-               }\r
-               \r
-       }\r
-       \r
-       private void createNewTemplate() {\r
-               try {\r
-                       RecordJobTemplate templ = new RecordJobTemplate(\r
-                               this.templateNameField.getText(),\r
-                               this.templateSummaryField.getText(),\r
-                               this.jobNameField.getText(),\r
-                               this.enginePathFC.getSelectedFile(),\r
-                               this.engineParameterField.getText(),\r
-                               this.demoFileFC.getSelectedFile(),\r
-                               this.relativeDemoPathField.getText(),\r
-                               this.dpVideoDirFC.getSelectedFile(),\r
-                               this.videoDestinationFC.getSelectedFile(),\r
-                               this.execBeforeField.getText(),\r
-                               this.execAfterField.getText()\r
-                       );\r
-                       this.saveEncoderPluginSettings(templ);\r
-                       this.tableModel.addRecordJobTemplate(templ);\r
-                       dispose();\r
-               } catch (NullPointerException e) {\r
-                       DemoRecorderUtils.showNonCriticalErrorDialog("Make sure that you chose a file/directory in each case!", e, true);\r
-               } catch (Exception e) {\r
-                       DemoRecorderUtils.showNonCriticalErrorDialog(e);\r
-                       return;\r
-               }\r
-       }\r
-       \r
-       private void editTemplate() {\r
-               try {\r
-                       RecordJobTemplate template = (RecordJobTemplate) this.job;\r
-                       template.setName(this.templateNameField.getText());\r
-                       template.setSummary(this.templateSummaryField.getText());\r
-                       template.setJobName(this.jobNameField.getText());\r
-                       template.setEnginePath(this.enginePathFC.getSelectedFile());\r
-                       template.setEngineParameters(this.engineParameterField.getText());\r
-                       template.setDpVideoPath(this.dpVideoDirFC.getSelectedFile());\r
-                       template.setRelativeDemoPath(this.relativeDemoPathField.getText());\r
-                       template.setDemoFile(this.demoFileFC.getSelectedFile());\r
-                       template.setExecuteBeforeCap(this.execBeforeField.getText());\r
-                       template.setExecuteAfterCap(this.execAfterField.getText());\r
-                       template.setVideoDestination(this.videoDestinationFC.getSelectedFile());\r
-                       this.saveEncoderPluginSettings(template);\r
-                       dispose();\r
-               } catch (Exception e) {\r
-                       DemoRecorderUtils.showNonCriticalErrorDialog(e);\r
-                       return;\r
-               }\r
-       }\r
-       \r
-       private void saveEncoderPluginSettings(RecordJob job) {\r
-               Set<String> keys = this.pluginDialogSettings.keySet();\r
-               //remember, the keys are concatenated, containing both the category and actual key \r
-               for (String key : keys) {\r
-                       JComponent component = this.pluginDialogSettings.get(key);\r
-                       if (component instanceof JCheckBox) {\r
-                               JCheckBox checkbox = (JCheckBox) component;\r
-                               job.setEncoderPluginSetting(NDRPreferences.getCategory(key), NDRPreferences.getKey(key), String.valueOf(checkbox.isSelected()));\r
-                       } else if (component instanceof JFileChooser) {\r
-                               JFileChooser fileChooser = (JFileChooser) component;\r
-                               if (fileChooser.getSelectedFile() != null) {\r
-                                       String path = fileChooser.getSelectedFile().getAbsolutePath();\r
-                                       job.setEncoderPluginSetting(NDRPreferences.getCategory(key), NDRPreferences.getKey(key), path);\r
-                               }\r
-                       } else if (component instanceof JTextField) {\r
-                               JTextField textField = (JTextField) component;\r
-                               job.setEncoderPluginSetting(NDRPreferences.getCategory(key), NDRPreferences.getKey(key), textField.getText());\r
-                       }\r
-               }\r
-       }\r
-       \r
-       private static class FileChooserButton extends JButton {\r
-               private static final long serialVersionUID = 1335571540372856959L;\r
-               public FileChooserButton() {\r
-                       super("...");\r
-               }\r
-       }\r
-       \r
-       private JFileChooser createConfiguredFileChooser() {\r
-               JFileChooser fc = new JFileChooser();\r
-               fc.setFileHidingEnabled(false);\r
-               fc.setFileFilter(userDirFilter);\r
-               return fc;\r
-       }\r
-}\r
+package com.nexuiz.demorecorder.ui.swinggui;
+
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.ScrollPaneConstants;
+import javax.swing.border.EmptyBorder;
+import javax.swing.filechooser.FileFilter;
+
+import net.miginfocom.swing.MigLayout;
+
+import org.jdesktop.swingx.JXTable;
+import org.jdesktop.swingx.JXTitledSeparator;
+
+import com.nexuiz.demorecorder.application.DemoRecorderApplication;
+import com.nexuiz.demorecorder.application.DemoRecorderUtils;
+import com.nexuiz.demorecorder.application.NDRPreferences;
+import com.nexuiz.demorecorder.application.jobs.RecordJob;
+import com.nexuiz.demorecorder.application.plugins.EncoderPlugin;
+import com.nexuiz.demorecorder.ui.swinggui.tablemodels.RecordJobTemplatesTableModel;
+import com.nexuiz.demorecorder.ui.swinggui.utils.SwingGUIUtils;
+
+/**
+ * Shows the dialog that allows to create a new job, create one from a template
+ * or edit an existing job.
+ */
+
+public class JobDialog extends JDialog implements ActionListener {
+       private static final long serialVersionUID = 6926246716804560522L;
+       public static final int CREATE_NEW_JOB = 0;
+       public static final int EDIT_JOB = 1;
+       public static final int CREATE_NEW_TEMPLATE = 2;
+       public static final int EDIT_TEMPLATE = 3;
+       public static final int CREATE_JOB_FROM_TEMPLATE = 4;
+
+       private DemoRecorderApplication appLayer;
+       private RecordJobTemplatesTableModel tableModel;
+//     private JXTable templatesTable;
+       private Frame parentFrame;
+       private int dialogType;
+       private RecordJob job = null;
+       private JPanel inputPanel;
+       private JPanel buttonPanel;
+
+       private JTextField templateNameField;
+       private JTextField templateSummaryField;
+       private JTextField enginePathField;
+       private JButton enginePathChooserButton;
+       private JTextField engineParameterField;
+       private JTextField dpVideoDirField;
+       private JButton dpVideoDirChooserButton;
+       private JTextField relativeDemoPathField;
+       private JTextField jobNameField;
+       private JTextField demoFileField;
+       private JButton demoFileChooserButton;
+       private JTextField startSecondField;
+       private JTextField endSecondField;
+       private JTextArea execBeforeField;
+       private JTextArea execAfterField;
+       private JTextField videoDestinationField;
+       private JButton videoDestinationChooserButton;
+       
+       private JButton createButton;
+       private JButton cancelButton;
+       
+       //file choosers
+       private JFileChooser enginePathFC;
+       private JFileChooser dpVideoDirFC;
+       private JFileChooser demoFileFC;
+       private JFileChooser videoDestinationFC;
+       
+       private FileFilter userDirFilter = new NexuizUserDirFilter();
+       
+       private Map<String, JComponent> pluginDialogSettings = new HashMap<String, JComponent>();
+
+       /**
+        * Constructor to create a dialog when creating a new job.
+        * @param owner
+        * @param appLayer
+        */
+       public JobDialog(Frame owner, DemoRecorderApplication appLayer) {
+               super(owner, true);
+               this.parentFrame = owner;
+               this.dialogType = CREATE_NEW_JOB;
+               this.appLayer = appLayer;
+               setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+
+               setTitle("Create new job");
+
+               this.setupLayout();
+       }
+       
+       /**
+        * Constructor to create a dialog when creating a new template.
+        * @param owner
+        * @param dialogType
+        * @param appLayer
+        */
+       public JobDialog(Frame owner, RecordJobTemplatesTableModel tableModel, JXTable templatesTable, DemoRecorderApplication appLayer) {
+               super(owner, true);
+               this.parentFrame = owner;
+               this.dialogType = CREATE_NEW_TEMPLATE;
+               this.tableModel = tableModel;
+               this.appLayer = appLayer;
+//             this.templatesTable = templatesTable; seems we don't need it
+               setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+               setTitle("Create new template");
+
+               this.setupLayout();
+       }
+       
+       /**
+        * Constructor to use when creating a new job from a template, or when editing a template.
+        * @param owner
+        * @param template
+        * @param type either CREATE_JOB_FROM_TEMPLATE or EDIT_TEMPLATE
+        */
+       public JobDialog(Frame owner, RecordJobTemplate template, DemoRecorderApplication appLayer, int type) {
+               super(owner, true);
+               this.parentFrame = owner;
+               
+               this.job = template;
+               this.appLayer = appLayer;
+               setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+               
+               if (type != CREATE_JOB_FROM_TEMPLATE && type != EDIT_TEMPLATE) {
+                       throw new RuntimeException("Illegal paraameter \"type\"");
+               }
+               
+               this.dialogType = type;
+               if (type == CREATE_JOB_FROM_TEMPLATE) {
+                       setTitle("Create job from template");
+               } else {
+                       setTitle("Edit template");
+               }
+
+               this.setupLayout();
+       }
+       
+       /**
+        * Constructor to create a dialog to be used when editing an existing job.
+        * @param owner
+        * @param job
+        */
+       public JobDialog(Frame owner, RecordJob job, DemoRecorderApplication appLayer) {
+               super(owner, true);
+               this.parentFrame = owner;
+               this.dialogType = EDIT_JOB;
+               this.appLayer = appLayer;
+               setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+
+               setTitle("Edit job");
+               this.job = job;
+
+               this.setupLayout();
+       }
+       
+       
+       
+       public void showDialog() {
+               this.pack();
+               Toolkit t = Toolkit.getDefaultToolkit();
+               Dimension screenSize = t.getScreenSize();
+               if (getHeight() > screenSize.height) {
+                       Dimension newPreferredSize = getPreferredSize();
+                       newPreferredSize.height = screenSize.height - 100;
+                       setPreferredSize(newPreferredSize);
+                       this.pack();
+               }
+               this.setLocationRelativeTo(this.parentFrame);
+               this.setVisible(true);
+       }
+
+       private void setupLayout() {
+//             setLayout(new MigLayout("wrap 1", "[grow,fill]", "[]20[]"));
+               setLayout(new MigLayout("wrap 1", "[grow,fill]", "[][]"));
+               this.setupInputMask();
+               this.setupButtonPart();
+
+       }
+
+       private void setupInputMask() {
+               inputPanel = new JPanel(new MigLayout("insets 0,wrap 3", "[][250::,grow,fill][30::]"));
+               JScrollPane inputScrollPane = new JScrollPane(inputPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
+               inputScrollPane.setBorder(new EmptyBorder(0,0,0,0));
+               
+               JXTitledSeparator environmentHeading = new JXTitledSeparator("Environment settings");
+               inputPanel.add(environmentHeading, "span 3,grow");
+
+               this.setupTemplateNameAndSummary();
+               this.setupEnginePath();
+               this.setupEngineParameters();
+               this.setupDPVideoDir();
+               this.setupRelativeDemoPath();
+
+               JXTitledSeparator jobSettingsHeading = new JXTitledSeparator("Job settings");
+               inputPanel.add(jobSettingsHeading, "span 3,grow");
+
+               this.setupJobName();
+               this.setupDemoFile();
+               this.setupStartSecond();
+               this.setupEndSecond();
+               this.setupExecBefore();
+               this.setupExecAfter();
+               this.setupVideoDestination();
+               
+               this.setupPluginPreferences();
+
+               getContentPane().add(inputScrollPane);
+       }
+       
+       private void setupTemplateNameAndSummary() {
+               if (this.dialogType != CREATE_NEW_TEMPLATE && this.dialogType != EDIT_TEMPLATE) {
+                       return;
+               }
+               
+               //layout stuff
+               inputPanel.add(new JLabel("Template name:"));
+               templateNameField = new JTextField();
+               inputPanel.add(templateNameField, "wrap");
+               
+               inputPanel.add(new JLabel("Summary:"));
+               templateSummaryField = new JTextField();
+               inputPanel.add(templateSummaryField, "wrap");
+               
+               //UI logic stuff
+               if (this.dialogType == EDIT_TEMPLATE) {
+                       RecordJobTemplate template = (RecordJobTemplate) this.job;
+                       templateNameField.setText(template.getName());
+                       templateSummaryField.setText(template.getSummary());
+               }
+       }
+       
+       private void setupEnginePath() {
+               //layout stuff
+               inputPanel.add(new JLabel("Engine:"));
+               enginePathField = new JTextField();
+               enginePathField.setEditable(false);
+               inputPanel.add(enginePathField);
+               enginePathChooserButton = new FileChooserButton();
+               inputPanel.add(enginePathChooserButton);
+               
+               //UI logic stuff
+               this.enginePathFC = createConfiguredFileChooser();
+               enginePathChooserButton.addActionListener(this);
+               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {
+                       this.enginePathFC.setSelectedFile(this.job.getEnginePath());
+                       this.enginePathField.setText(this.job.getEnginePath().getAbsolutePath());
+               }
+       }
+       
+       private void setupEngineParameters() {
+               //layout stuff
+               inputPanel.add(new JLabel("Engine parameters:"));
+               engineParameterField = new JTextField();
+               inputPanel.add(engineParameterField, "wrap");
+               
+               //UI logic stuff
+               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {
+                       engineParameterField.setText(this.job.getEngineParameters());
+               }
+       }
+       
+       private void setupDPVideoDir() {
+               //layout stuff
+               inputPanel.add(new JLabel("DPVideo directory:"));
+               dpVideoDirField = new JTextField();
+               dpVideoDirField.setEditable(false);
+               inputPanel.add(dpVideoDirField);
+               dpVideoDirChooserButton = new FileChooserButton();
+               inputPanel.add(dpVideoDirChooserButton);
+               
+               //UI logic stuff
+               dpVideoDirChooserButton.addActionListener(this);
+               this.dpVideoDirFC = createConfiguredFileChooser();
+               this.dpVideoDirFC.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {
+                       this.dpVideoDirFC.setSelectedFile(this.job.getDpVideoPath());
+                       this.dpVideoDirField.setText(this.job.getDpVideoPath().getAbsolutePath());
+               }
+       }
+       
+       private void setupRelativeDemoPath() {
+               //layout stuff
+               inputPanel.add(new JLabel("Relative demo path:"));
+               relativeDemoPathField = new JTextField();
+               inputPanel.add(relativeDemoPathField, "wrap 20");
+               
+               //UI logic stuff
+               if (this.dialogType == CREATE_NEW_JOB || this.dialogType == CREATE_NEW_TEMPLATE) {
+                       relativeDemoPathField.setText("demos");
+               }
+               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {
+                       relativeDemoPathField.setText(this.job.getRelativeDemoPath());
+               }
+       }
+       
+       private void setupJobName() {
+               inputPanel.add(new JLabel("Job name:"));
+               
+               jobNameField = new JTextField();
+               inputPanel.add(jobNameField, "wrap");
+               
+               //UI logic stuff
+               if (this.dialogType != CREATE_NEW_TEMPLATE && this.dialogType != CREATE_NEW_JOB) {
+                       jobNameField.setText(this.job.getJobName());
+               }
+       }
+       
+       private void setupDemoFile() {
+               String label;
+               if (this.dialogType == CREATE_NEW_JOB || this.dialogType == EDIT_JOB || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {
+                       label = "Demo file:";
+               } else {
+                       label = "Demo directory:";
+               }
+               
+               //layout stuff
+               inputPanel.add(new JLabel(label));
+               demoFileField = new JTextField();
+               demoFileField.setEditable(false);
+               inputPanel.add(demoFileField);
+               demoFileChooserButton = new FileChooserButton();
+               inputPanel.add(demoFileChooserButton);
+               
+               //UI logic stuff
+               this.demoFileFC = createConfiguredFileChooser();
+               demoFileChooserButton.addActionListener(this);
+               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {
+                       if (this.dialogType == CREATE_JOB_FROM_TEMPLATE) {
+                               this.demoFileFC.setCurrentDirectory(this.job.getDemoFile());
+                       } else {
+                               this.demoFileFC.setSelectedFile(this.job.getDemoFile());
+                       }
+                       
+                       this.demoFileField.setText(this.job.getDemoFile().getAbsolutePath());
+               }
+               
+               //only specify directories for templates
+               if (this.dialogType == CREATE_NEW_TEMPLATE || this.dialogType == EDIT_TEMPLATE) {
+                       this.demoFileFC.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+               }
+       }
+       
+       private void setupStartSecond() {
+               //only exists for jobs, not for templates
+               if (this.dialogType != CREATE_NEW_JOB && this.dialogType != EDIT_JOB && this.dialogType != CREATE_JOB_FROM_TEMPLATE) {
+                       return;
+               }
+               
+               //layout stuff
+               inputPanel.add(new JLabel("Start second:"));
+               startSecondField = new JTextField();
+               inputPanel.add(startSecondField, "wrap");
+               
+               //UI logic stuff
+               if (this.dialogType == EDIT_JOB) {
+                       startSecondField.setText(String.valueOf( this.job.getStartSecond() ));
+               }
+       }
+       
+       private void setupEndSecond() {
+               //only exists for jobs, not for templates
+               if (this.dialogType != CREATE_NEW_JOB && this.dialogType != EDIT_JOB && this.dialogType != CREATE_JOB_FROM_TEMPLATE) {
+                       return;
+               }
+               
+               //layout stuff
+               inputPanel.add(new JLabel("End second:"));
+               endSecondField = new JTextField();
+               inputPanel.add(endSecondField, "wrap");
+               
+               //UI logic stuff
+               if (this.dialogType == EDIT_JOB) {
+                       endSecondField.setText(String.valueOf( this.job.getEndSecond() ));
+               }
+       }
+       
+       private void setupExecBefore() {
+               //layout stuff
+               inputPanel.add(new JLabel("Exec before capture:"));
+               execBeforeField = new JTextArea(3, 1);
+               inputPanel.add(new JScrollPane(execBeforeField), "wrap");
+               
+               //UI logic stuff
+               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {
+                       execBeforeField.setText(this.job.getExecuteBeforeCap());
+               }
+       }
+       
+       private void setupExecAfter() {
+               //layout stuff
+               inputPanel.add(new JLabel("Exec after capture:"));
+               execAfterField = new JTextArea(3, 1);
+               inputPanel.add(new JScrollPane(execAfterField), "wrap");
+               
+               //UI logic stuff
+               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {
+                       execAfterField.setText(this.job.getExecuteAfterCap());
+               }
+       }
+       
+       private void setupVideoDestination() {
+               //layout stuff
+               inputPanel.add(new JLabel("Video destination:"));
+               videoDestinationField = new JTextField();
+               videoDestinationField.setEditable(false);
+               inputPanel.add(videoDestinationField);
+               videoDestinationChooserButton = new FileChooserButton();
+               inputPanel.add(videoDestinationChooserButton, "wrap 20");
+               
+               //UI logic stuff
+               videoDestinationChooserButton.addActionListener(this);
+               this.videoDestinationFC = createConfiguredFileChooser();
+               if (this.dialogType == EDIT_JOB || this.dialogType == EDIT_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {
+                       if (this.dialogType == CREATE_JOB_FROM_TEMPLATE) {
+                               this.videoDestinationFC.setCurrentDirectory(this.job.getVideoDestination());
+                       } else {
+                               this.videoDestinationFC.setSelectedFile(this.job.getVideoDestination());
+                       }
+                       
+                       this.videoDestinationField.setText(this.job.getVideoDestination().getAbsolutePath());
+               }
+               if (this.dialogType == CREATE_NEW_TEMPLATE || this.dialogType == EDIT_TEMPLATE) {
+                       this.videoDestinationFC.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+               }
+       }
+       
+       private void setupPluginPreferences() {
+               for (EncoderPlugin plugin : this.appLayer.getEncoderPlugins()) {
+                       String pluginName = plugin.getName();
+                       //only display settings if the plugin actually has any...
+                       Properties jobSpecificDefaultPluginPreferences = plugin.getJobSpecificPreferences();
+                       Properties jobPluginPreferences = null;
+                       if (this.job != null) {
+                               jobPluginPreferences = this.job.getEncoderPluginSettings(plugin);
+                       }
+                       if (jobSpecificDefaultPluginPreferences.size() > 0 && plugin.isEnabled()) {
+                               //add heading
+                               JXTitledSeparator pluginHeading = new JXTitledSeparator(pluginName + " plugin settings");
+                               inputPanel.add(pluginHeading, "span 3,grow");
+                               
+                               for (String pluginPreferenceKey : plugin.getJobSpecificPreferencesOrder()) {
+                                       String value = jobSpecificDefaultPluginPreferences.getProperty(pluginPreferenceKey);
+                                       if (this.job != null) {
+                                               if (jobPluginPreferences.containsKey(pluginPreferenceKey)) {
+                                                       value = jobPluginPreferences.getProperty(pluginPreferenceKey);
+                                               }
+                                       }
+                                       
+                                       this.setupSinglePluginSetting(plugin, pluginPreferenceKey, value);
+                               }
+                       }
+               }
+       }
+       
+       private void setupSinglePluginSetting(EncoderPlugin plugin, String key, String value) {
+               inputPanel.add(new JLabel(key + ":"));
+               
+               if (SwingGUIUtils.isBooleanValue(value)) {
+                       JCheckBox checkbox = new JCheckBox();
+                       checkbox.setSelected(Boolean.valueOf(value));
+                       inputPanel.add(checkbox, "wrap");
+                       this.pluginDialogSettings.put(NDRPreferences.getConcatenatedKey(plugin.getName(), key), checkbox);
+               } else if (SwingGUIUtils.isFileChooser(value)) {
+                       final JFileChooser fc = new JFileChooser();
+                       fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+                       JButton fcButton = new JButton("...");
+                       final JTextField filePathField = new JTextField();
+                       filePathField.setEditable(false);
+                       inputPanel.add(filePathField);
+                       fcButton.addActionListener(new ActionListener() {
+                               @Override
+                               public void actionPerformed(ActionEvent e) {
+                                       int returnValue = fc.showOpenDialog(JobDialog.this);
+                                       if (returnValue == JFileChooser.APPROVE_OPTION) {
+                                               File selectedFile = fc.getSelectedFile();
+                                               filePathField.setText(selectedFile.getAbsolutePath());
+                                       }
+                               }
+                       });
+                       
+                       try {
+                               File selectedFile = new File(value);
+                               if (selectedFile.exists()) {
+                                       fc.setSelectedFile(selectedFile);
+                                       filePathField.setText(selectedFile.getAbsolutePath());
+                               }
+                       } catch (Throwable e) {}
+                       this.pluginDialogSettings.put(NDRPreferences.getConcatenatedKey(plugin.getName(), key), fc);
+                       inputPanel.add(fcButton);
+               } else {
+                       //textfield
+                       JTextField textField = new JTextField();
+                       textField.setText(value);
+                       this.pluginDialogSettings.put(NDRPreferences.getConcatenatedKey(plugin.getName(), key), textField);
+                       inputPanel.add(textField, "wrap");
+               }
+       }
+
+       private void setupButtonPart() {
+               String createButtonText;
+               if (this.dialogType == CREATE_NEW_JOB || this.dialogType == CREATE_NEW_TEMPLATE || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {
+                       createButtonText = "Create";
+               } else {
+                       createButtonText = "Save";
+               }
+               buttonPanel = new JPanel(new MigLayout("insets 0"));
+               createButton = new JButton(createButtonText);
+               createButton.addActionListener(this);
+               cancelButton = new JButton("Cancel");
+               cancelButton.addActionListener(this);
+               
+               buttonPanel.add(createButton);
+               buttonPanel.add(cancelButton);
+
+               getContentPane().add(buttonPanel);
+       }
+       
+       
+       public void actionPerformed(ActionEvent e) {
+               if (e.getSource() == enginePathChooserButton) {
+                       int returnValue = this.enginePathFC.showOpenDialog(this);
+                       if (returnValue == JFileChooser.APPROVE_OPTION) {
+                               File selectedFile = this.enginePathFC.getSelectedFile();
+                               this.enginePathField.setText(selectedFile.getAbsolutePath());
+                       }
+               } else if (e.getSource() == dpVideoDirChooserButton) {
+                       int returnValue = this.dpVideoDirFC.showOpenDialog(this);
+                       if (returnValue == JFileChooser.APPROVE_OPTION) {
+                               File selectedFile = this.dpVideoDirFC.getSelectedFile();
+                               this.dpVideoDirField.setText(selectedFile.getAbsolutePath());
+                       }
+               } else if (e.getSource() == demoFileChooserButton) {
+                       int returnValue = this.demoFileFC.showOpenDialog(this);
+                       if (returnValue == JFileChooser.APPROVE_OPTION) {
+                               File selectedFile = this.demoFileFC.getSelectedFile();
+                               if (this.dialogType == CREATE_NEW_JOB || this.dialogType == EDIT_JOB || this.dialogType == CREATE_JOB_FROM_TEMPLATE) {
+                                       this.demoFileField.setText(DemoRecorderUtils.getJustFileNameOfPath(selectedFile));
+                               } else {
+                                       //template, show full path of directory
+                                       this.demoFileField.setText(selectedFile.getAbsolutePath());
+                               }
+                               
+                       }
+               } else if (e.getSource() == videoDestinationChooserButton) {
+                       int returnValue = this.videoDestinationFC.showSaveDialog(this);
+                       if (returnValue == JFileChooser.APPROVE_OPTION) {
+                               File selectedFile = this.videoDestinationFC.getSelectedFile();
+                               this.videoDestinationField.setText(selectedFile.getAbsolutePath());
+                       }
+               } else if (e.getSource() == createButton) {
+                       switch (this.dialogType) {
+                       case CREATE_NEW_JOB:
+                       case CREATE_JOB_FROM_TEMPLATE:
+                               this.requestNewRecordJob(); break;
+                       case CREATE_NEW_TEMPLATE:
+                               this.createNewTemplate();
+                               break;
+                       case EDIT_JOB:
+                               this.editJob();
+                               break;
+                       case EDIT_TEMPLATE:
+                               this.editTemplate();
+                               break;
+                       }
+               } else if (e.getSource() == cancelButton) {
+                       dispose();
+               }
+       }
+       
+       private void requestNewRecordJob() {
+               float startSecond, endSecond = -1;
+               try {
+                       startSecond = Float.valueOf(this.startSecondField.getText());
+                       endSecond = Float.valueOf(this.endSecondField.getText());
+               } catch (Exception e) {
+                       DemoRecorderUtils.showNonCriticalErrorDialog("Make sure that start and end second are floating point numbers", e, true);
+                       return;
+               }
+               
+               try {
+                       RecordJob j = this.appLayer.createRecordJob(
+                               this.jobNameField.getText(),
+                               this.enginePathFC.getSelectedFile(),
+                               this.engineParameterField.getText(),
+                               this.demoFileFC.getSelectedFile(),
+                               this.relativeDemoPathField.getText(),
+                               this.dpVideoDirFC.getSelectedFile(),
+                               this.videoDestinationFC.getSelectedFile(),
+                               this.execBeforeField.getText(),
+                               this.execAfterField.getText(),
+                               startSecond,
+                               endSecond
+                       );
+                       this.saveEncoderPluginSettings(j);
+                       dispose();
+               } catch (Exception e) {
+                       DemoRecorderUtils.showNonCriticalErrorDialog(e);
+                       return;
+               }
+               
+       }
+       
+       private void editJob() {
+               float startSecond, endSecond = -1;
+               try {
+                       startSecond = Float.valueOf(this.startSecondField.getText());
+                       endSecond = Float.valueOf(this.endSecondField.getText());
+               } catch (Exception e) {
+                       DemoRecorderUtils.showNonCriticalErrorDialog("Make sure that start and end second are floating point numbers", e, true);
+                       return;
+               }
+               
+               try {
+                       this.job.setJobName(this.jobNameField.getText());
+                       this.job.setEnginePath(this.enginePathFC.getSelectedFile());
+                       this.job.setEngineParameters(this.engineParameterField.getText());
+                       this.job.setDemoFile(this.demoFileFC.getSelectedFile());
+                       this.job.setRelativeDemoPath(this.relativeDemoPathField.getText());
+                       this.job.setDpVideoPath(this.dpVideoDirFC.getSelectedFile());
+                       this.job.setVideoDestination(this.videoDestinationFC.getSelectedFile());
+                       this.job.setExecuteBeforeCap(this.execBeforeField.getText());
+                       this.job.setExecuteAfterCap(this.execAfterField.getText());
+                       this.job.setStartSecond(startSecond);
+                       this.job.setEndSecond(endSecond);
+                       this.saveEncoderPluginSettings(this.job);
+                       this.appLayer.fireUserInterfaceUpdate(this.job);
+                       dispose();
+               } catch (Exception e) {
+                       DemoRecorderUtils.showNonCriticalErrorDialog(e);
+                       return;
+               }
+               
+       }
+       
+       private void createNewTemplate() {
+               try {
+                       RecordJobTemplate templ = new RecordJobTemplate(
+                               this.templateNameField.getText(),
+                               this.templateSummaryField.getText(),
+                               this.jobNameField.getText(),
+                               this.enginePathFC.getSelectedFile(),
+                               this.engineParameterField.getText(),
+                               this.demoFileFC.getSelectedFile(),
+                               this.relativeDemoPathField.getText(),
+                               this.dpVideoDirFC.getSelectedFile(),
+                               this.videoDestinationFC.getSelectedFile(),
+                               this.execBeforeField.getText(),
+                               this.execAfterField.getText()
+                       );
+                       this.saveEncoderPluginSettings(templ);
+                       this.tableModel.addRecordJobTemplate(templ);
+                       dispose();
+               } catch (NullPointerException e) {
+                       DemoRecorderUtils.showNonCriticalErrorDialog("Make sure that you chose a file/directory in each case!", e, true);
+               } catch (Exception e) {
+                       DemoRecorderUtils.showNonCriticalErrorDialog(e);
+                       return;
+               }
+       }
+       
+       private void editTemplate() {
+               try {
+                       RecordJobTemplate template = (RecordJobTemplate) this.job;
+                       template.setName(this.templateNameField.getText());
+                       template.setSummary(this.templateSummaryField.getText());
+                       template.setJobName(this.jobNameField.getText());
+                       template.setEnginePath(this.enginePathFC.getSelectedFile());
+                       template.setEngineParameters(this.engineParameterField.getText());
+                       template.setDpVideoPath(this.dpVideoDirFC.getSelectedFile());
+                       template.setRelativeDemoPath(this.relativeDemoPathField.getText());
+                       template.setDemoFile(this.demoFileFC.getSelectedFile());
+                       template.setExecuteBeforeCap(this.execBeforeField.getText());
+                       template.setExecuteAfterCap(this.execAfterField.getText());
+                       template.setVideoDestination(this.videoDestinationFC.getSelectedFile());
+                       this.saveEncoderPluginSettings(template);
+                       dispose();
+               } catch (Exception e) {
+                       DemoRecorderUtils.showNonCriticalErrorDialog(e);
+                       return;
+               }
+       }
+       
+       private void saveEncoderPluginSettings(RecordJob job) {
+               Set<String> keys = this.pluginDialogSettings.keySet();
+               //remember, the keys are concatenated, containing both the category and actual key 
+               for (String key : keys) {
+                       JComponent component = this.pluginDialogSettings.get(key);
+                       if (component instanceof JCheckBox) {
+                               JCheckBox checkbox = (JCheckBox) component;
+                               job.setEncoderPluginSetting(NDRPreferences.getCategory(key), NDRPreferences.getKey(key), String.valueOf(checkbox.isSelected()));
+                       } else if (component instanceof JFileChooser) {
+                               JFileChooser fileChooser = (JFileChooser) component;
+                               if (fileChooser.getSelectedFile() != null) {
+                                       String path = fileChooser.getSelectedFile().getAbsolutePath();
+                                       job.setEncoderPluginSetting(NDRPreferences.getCategory(key), NDRPreferences.getKey(key), path);
+                               }
+                       } else if (component instanceof JTextField) {
+                               JTextField textField = (JTextField) component;
+                               job.setEncoderPluginSetting(NDRPreferences.getCategory(key), NDRPreferences.getKey(key), textField.getText());
+                       }
+               }
+       }
+       
+       private static class FileChooserButton extends JButton {
+               private static final long serialVersionUID = 1335571540372856959L;
+               public FileChooserButton() {
+                       super("...");
+               }
+       }
+       
+       private JFileChooser createConfiguredFileChooser() {
+               JFileChooser fc = new JFileChooser();
+               fc.setFileHidingEnabled(false);
+               fc.setFileFilter(userDirFilter);
+               return fc;
+       }
+}