/**
* Created : Mar 23, 2012
*
* @author pquiring
*/
import java.awt.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.tree.*;
import javaforce.*;
public class ProjectDialog extends javax.swing.JDialog {
/**
* Creates new form ProjectDialog
*/
public ProjectDialog(java.awt.Frame parent, boolean modal, Type type, String loadFilename) {
super(parent, modal);
initComponents();
setPosition();
if (loadFilename != null) {
loadProject(loadFilename);
xmlFiles = xml.getTag(new String[] {"jfburn", "files"});
xmlOptions = xml.getTag(new String[] {"jfburn", "options"});
XML.XMLTag typeTag = xml.getTag(new String[] {"jfburn", "options", "type"});
XML.XMLTag nameTag = xml.getTag(new String[] {"jfburn", "options", "name"});
if ((xmlFiles == null) || (xmlOptions == null) || (typeTag == null)) {
JF.showError("Error", "Invalid Project File");
dispose();
return;
}
xmlFiles.content = nameTag.content;
if (typeTag.content.equals("audio")) type = Type.audio;
if (typeTag.content.equals("data")) type = Type.data;
if (typeTag.content.equals("video")) type = Type.video;
if (type == Type.unknown) {
JF.showError("Error", "Invalid Project File");
dispose();
return;
}
} else {
xml.root.setName("jfburn");
xmlFiles = xml.addTag(xml.root, "files", "", "New Disc"); //NOTE : This is not a leaf node so the content is lost on save
xmlOptions = xml.addTag(xml.root, "options", "", "");
xml.addTag(xmlOptions, "type", "", type.toString());
xml.addTag(xmlOptions, "name", "", "New Disc"); //backup of xmlFiles content for saving to disk
}
this.type = type;
if (type == Type.audio) {
toolbar.remove(createFolder);
}
xml.setRoot(xmlFiles);
xmlFiles.useContentForName = true;
showAll();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
files = new javax.swing.JTree();
toolbar = new javax.swing.JToolBar();
add = new javax.swing.JButton();
remove = new javax.swing.JButton();
rename = new javax.swing.JButton();
createFolder = new javax.swing.JButton();
burn = new javax.swing.JButton();
createImage = new javax.swing.JButton();
save = new javax.swing.JButton();
options = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle("Project");
files.setModel(xml.getTreeModel());
jScrollPane1.setViewportView(files);
toolbar.setFloatable(false);
toolbar.setRollover(true);
add.setText("Add Files/Folders");
add.setFocusable(false);
add.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
add.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
add.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
addActionPerformed(evt);
}
});
toolbar.add(add);
remove.setText("Remove");
remove.setFocusable(false);
remove.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
remove.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
remove.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
removeActionPerformed(evt);
}
});
toolbar.add(remove);
rename.setText("Rename");
rename.setFocusable(false);
rename.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
rename.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
rename.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
renameActionPerformed(evt);
}
});
toolbar.add(rename);
createFolder.setText("Create Folder");
createFolder.setFocusable(false);
createFolder.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
createFolder.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
createFolder.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
createFolderActionPerformed(evt);
}
});
toolbar.add(createFolder);
burn.setText("Burn Disc");
burn.setFocusable(false);
burn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
burn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
burn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
burnActionPerformed(evt);
}
});
toolbar.add(burn);
createImage.setText("Create Image");
createImage.setFocusable(false);
createImage.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
createImage.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
createImage.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
createImageActionPerformed(evt);
}
});
toolbar.add(createImage);
save.setText("Save");
save.setFocusable(false);
save.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
save.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
save.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
saveActionPerformed(evt);
}
});
toolbar.add(save);
options.setText("Options");
options.setFocusable(false);
options.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
options.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
options.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optionsActionPerformed(evt);
}
});
toolbar.add(options);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(toolbar, javax.swing.GroupLayout.DEFAULT_SIZE, 684, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(toolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 412, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void addActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addActionPerformed
addFiles();
}//GEN-LAST:event_addActionPerformed
private void removeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeActionPerformed
removeFiles();
}//GEN-LAST:event_removeActionPerformed
private void createFolderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createFolderActionPerformed
createFolder();
}//GEN-LAST:event_createFolderActionPerformed
private void burnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_burnActionPerformed
burnDisc();
}//GEN-LAST:event_burnActionPerformed
private void createImageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createImageActionPerformed
createImage();
}//GEN-LAST:event_createImageActionPerformed
private void saveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveActionPerformed
saveProject();
}//GEN-LAST:event_saveActionPerformed
private void optionsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optionsActionPerformed
JDialog dialog = new OptionsDialog(BurnApp.This, true, xml, xmlOptions);
dialog.setVisible(true);
}//GEN-LAST:event_optionsActionPerformed
private void renameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_renameActionPerformed
rename();
}//GEN-LAST:event_renameActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton add;
private javax.swing.JButton burn;
private javax.swing.JButton createFolder;
private javax.swing.JButton createImage;
private javax.swing.JTree files;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JButton options;
private javax.swing.JButton remove;
private javax.swing.JButton rename;
private javax.swing.JButton save;
private javax.swing.JToolBar toolbar;
// End of variables declaration//GEN-END:variables
public enum Type {unknown, audio, data, video};
private XML xml = new XML();
private XML.XMLTag xmlFiles, xmlOptions;
private Type type;
private String getName(String fullPath) {
int idx = fullPath.lastIndexOf("/");
if (idx == -1) return fullPath;
return fullPath.substring(idx+1);
}
private void addFolder(XML.XMLTag parent, File folder) {
File files[] = folder.listFiles();
String folderPath = folder.getAbsolutePath();
XML.XMLTag child = xml.addTag(parent, getName(folderPath), "", folderPath);
for(int a=0;a<files.length;a++) {
if (files[a].isDirectory()) {
addFolder(child, files[a]);
} else {
String filePath = files[a].getAbsolutePath();
xml.addTag(child, getName(filePath), "", filePath);
}
}
}
private void addFiles() {
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
chooser.setMultiSelectionEnabled(false);
chooser.setCurrentDirectory(new File(JF.getCurrentPath()));
if (type == Type.audio) {
javax.swing.filechooser.FileFilter ff_wav = new javax.swing.filechooser.FileFilter() {
public boolean accept(File file) {
if (file.isDirectory()) return true;
return (file.getName().endsWith(".wav"));
}
public String getDescription() {
return "Audio Files (*.wav)";
}
};
chooser.addChoosableFileFilter(ff_wav);
chooser.setFileFilter(ff_wav);
}
if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return;
String filename = chooser.getSelectedFile().getAbsolutePath();
File file = new File(filename);
if (file.isDirectory()) {
addFolder(xmlFiles, file);
} else {
xml.addTag(xmlFiles, getName(filename), "", filename);
}
showAll();
files.repaint();
}
private void removeFiles() {
if (files.getSelectionCount() != 1) return;
TreePath path = files.getSelectionPath();
XML.XMLTag tag = xml.getTag(path);
if (tag == xmlFiles) return;
xml.deleteTag(tag);
}
private void createFolder() {
TreePath sel = files.getSelectionPath();
if (sel == null) return;
String name = JF.getString("Enter folder name", "");
if ((name == null) || (name.length() == 0)) return;
XML.XMLTag tag = xml.getTag(sel);
xml.addTag(tag, name, "", name);
}
private void rename() {
TreePath sel = files.getSelectionPath();
if (sel == null) return;
XML.XMLTag tag = xml.getTag(sel);
String newName = JF.getString("Enter new name", tag.getName());
if (newName == null) return;
if (tag == xmlFiles) {
tag.content = newName;
xml.addSetTag(xmlOptions, "name", "", newName);
} else {
tag.setName(newName);
}
files.repaint();
}
private void burnDisc() {
switch (type){
case audio: burnAudioDisc(); return;
case video: //TODO - same as Data for now
case data: burnDataDisc(); return;
}
}
private void burnDataDisc() {
File tmpImage;
try {
tmpImage = File.createTempFile("jfburn-image", ".iso");
if (!saveImage(tmpImage.getAbsolutePath(), true)) return;
} catch (Exception e) {
JF.showError("Error", "Exception:" + e);
return;
}
this.setVisible(false);
JDialog dialog = new BurnDialog(BurnApp.This, true, new String[] {tmpImage.getAbsolutePath()});
dialog.setVisible(true);
this.setVisible(true);
}
private void burnAudioDisc() {
ArrayList<String> tracks = new ArrayList<String>();
XML.XMLTag tag;
int cnt = xmlFiles.getChildCount();
for(int a=0;a<cnt;a++) {
tracks.add(xmlFiles.getChildAt(a).content);
}
this.setVisible(false);
JDialog dialog = new BurnDialog(BurnApp.This, true, tracks.toArray(new String[0]));
dialog.setVisible(true);
this.setVisible(true);
}
private void burnVideoDisc() {
//TODO - create DVD files ???
File tmpImage;
try {
tmpImage = File.createTempFile("jfburn-image", ".iso");
saveImage(tmpImage.getAbsolutePath(), true);
} catch (Exception e) {
JF.showError("Error", "Exception:" + e);
return;
}
this.setVisible(false);
JDialog dialog = new BurnDialog(BurnApp.This, true, new String[] {tmpImage.getAbsolutePath()});
dialog.setVisible(true);
this.setVisible(true);
}
private void createImage() {
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(false);
chooser.setCurrentDirectory(new File(JF.getCurrentPath()));
javax.swing.filechooser.FileFilter ff_iso = new javax.swing.filechooser.FileFilter() {
public boolean accept(File file) {
if (file.isDirectory()) return true;
return (file.getName().endsWith(".iso"));
}
public String getDescription() {
return "ISO Files (*.iso)";
}
};
chooser.addChoosableFileFilter(ff_iso);
chooser.setFileFilter(ff_iso);
if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) return;
String filename = chooser.getSelectedFile().getAbsolutePath();
saveImage(filename, false);
}
private String escapeName(String name) {
return name.replaceAll("[\\\\]", "\\\\").replaceAll("[=]", "\\=");
}
private String getTagName(XML.XMLTag tag) {
StringBuilder sb = new StringBuilder();
sb.append(tag.getName());
while ((tag = tag.getParent()) != xmlFiles) {
sb.insert(0, "/");
sb.insert(0, tag.getName());
}
sb.insert(0, "/");
return escapeName(sb.toString());
}
private void writeTag(XML.XMLTag tag, OutputStream ios) throws Exception {
int cnt = tag.getChildCount();
if (cnt > 0) {
for(int a=0;a<cnt;a++) {
writeTag(tag.getChildAt(a), ios);
}
} else {
ios.write((getTagName(tag) + "=" + escapeName(tag.content) + "\n").getBytes());
}
}
private boolean saveImage(String filename, boolean auto) {
//mkisofs -path-list tmpFile -o filename <options>
try {
File tmpFile = File.createTempFile("jfburn-list-i", ".lst");
FileOutputStream fos = new FileOutputStream(tmpFile);
writeTag(xmlFiles, fos);
fos.close();
String cmd[] = {"mkisofs"
, "-graft-points"
, "-path-list", tmpFile.getAbsolutePath()
, "-o", filename
, "-udf", "-J", "-r"
, "-V", xmlFiles.content};
if (type == Type.video) {
cmd = Arrays.copyOf(cmd, cmd.length+1);
cmd[cmd.length-1] = "-dvd-video";
}
XML.XMLTag tag;
int bootType;
String bootFile;
tag = xml.getTag(new String[] {"jfburn", "options", "boot"});
if (tag != null) {
if (tag.content.equals("true")) {
tag = xml.getTag(new String[] {"jfburn", "options", "bootType"});
if (tag != null) {
bootType = JF.atoi(tag.content);
if ((bootType >= 0) && (bootType <= 3)) {
tag = xml.getTag(new String[] {"jfburn", "options", "bootFile"});
if (tag != null) {
bootFile = tag.content;
//add boot options
cmd = Arrays.copyOf(cmd, cmd.length+1);
cmd[cmd.length-1] = "-b";
cmd = Arrays.copyOf(cmd, cmd.length+1);
cmd[cmd.length-1] = bootFile; //TODO : must be relative to source files???
cmd = Arrays.copyOf(cmd, cmd.length+1);
cmd[cmd.length-1] = "-c";
cmd = Arrays.copyOf(cmd, cmd.length+1);
cmd[cmd.length-1] = "boot.cat";
//bootType : 0=floppy 1=hard drive 2=no emul
if (bootType == 1) {
cmd = Arrays.copyOf(cmd, cmd.length+1);
cmd[cmd.length-1] = "-hard-disk-boot";
}
if (bootType == 2) {
cmd = Arrays.copyOf(cmd, cmd.length+1);
cmd[cmd.length-1] = "-no-emul-boot";
}
}
}
}
}
}
JFTask task = new JFTask() {
ShellProcess sp;
public boolean work() {
String cmd[] = (String[])this.getProperty("cmd");
boolean auto = (Boolean)this.getProperty("auto");
this.setProgress(-1);
setLabel("Building ISO image...");
sp = new ShellProcess();
String output = sp.run(cmd, false);
this.setProgress(100);
if (abort)
setLabel("Building ISO image aborted!");
else
setLabel("Building ISO image complete!");
if (auto) this.dispose();
return !abort;
}
public void abort() {
sp.destroy();
abort = true;
}
};
task.setProperty("cmd", cmd);
task.setProperty("auto", (Boolean)auto);
ProgressDialog dialog = new ProgressDialog(null, true, task);
dialog.setVisible(true);
tmpFile.delete();
return task.getStatus();
} catch (Exception e) {
JF.showError("Error", "Exception:" + e);
return false;
}
}
private void saveProject() {
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(false);
File path = new File(JF.getUserPath() + "/jfburn");
path.mkdirs();
chooser.setCurrentDirectory(path);
javax.swing.filechooser.FileFilter ff_xml = new javax.swing.filechooser.FileFilter() {
public boolean accept(File file) {
if (file.isDirectory()) return true;
return (file.getName().endsWith(".burn"));
}
public String getDescription() {
return "Project Files (*.burn)";
}
};
chooser.addChoosableFileFilter(ff_xml);
chooser.setFileFilter(ff_xml);
if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) return;
String filename = chooser.getSelectedFile().getAbsolutePath();
if (!filename.endsWith(".burn")) filename += ".burn";
try {
FileOutputStream fos = new FileOutputStream(filename);
xml.write(fos);
fos.close();
} catch (Exception e) {
JF.showError("Error", "Failed to save project");
}
}
private void loadProject(String filename) {
try {
FileInputStream fis = new FileInputStream(filename);
xml.read(fis);
fis.close();
} catch (Exception e) {
JF.showError("Error", "Failed to load project");
}
}
private void showAll(XML.XMLTag tag) {
files.makeVisible(new TreePath(tag.getPath()));
int cnt = tag.getChildCount();
for(int a=0;a<cnt;a++) {
showAll(tag.getChildAt(a));
}
}
private void showAll() {
showAll(xmlFiles);
}
private void setPosition() {
Rectangle s = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
Dimension d = getPreferredSize();
setLocation(s.width/2 - d.width/2, s.height/2 - (d.height/2));
}
}