package se.runa.ui;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.Toolkit;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;
import se.runa.clipboard.ClipboardManager;
import se.runa.clipboard.ClipboardStrategy;
import se.runa.file.FileManager;
import se.runa.os.OS;
/**
*
* @author frebjo
*/
public class Runa extends JFrame implements TreeSelectionListener,
MouseListener, KeyListener, WindowFocusListener {
private static final long serialVersionUID = -8373859222083561374L;
public static void main(String[] args) throws Throwable {
System.setProperty("apple.laf.useScreenMenuBar", "true");
try {
new Runa();
} catch (Throwable e) {
e.printStackTrace();
throw e;
}
}
private Logger logger = Logger.getLogger(getClass().getName());
FileTable fileTable;
private JTree fileTree;
private FileTablePopupMenu fileTablePopupMenu;
public Runa() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setExtendedState(MAXIMIZED_BOTH);
addWindowFocusListener(this);
setJMenuBar(new MenuBar(this));
FileTreeModel treeModel = new FileTreeModel();
setTitle(treeModel.getAbsolutePath());
fileTable = new FileTable(new FileTableModel(treeModel));
fileTable.addMouseListener(this);
fileTable.addKeyListener(this);
fileTree = new JTree(treeModel);
fileTree.setCellRenderer(new FileTreeRenderer());
fileTree.setSelectionPath(new TreePath(treeModel));
fileTree.addTreeSelectionListener(this);
fileTree.addKeyListener(this);
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
new JScrollPane(fileTree), new JScrollPane(fileTable));
splitPane.setDividerLocation(350);
splitPane.setDividerSize(2);
getContentPane().add(splitPane);
fileTablePopupMenu = new FileTablePopupMenu(this);
setVisible(true);
}
void showErrorMsg(Throwable e) {
String msg = e.getMessage();
logger.log(Level.SEVERE, msg, e);
showErrorMsg(msg);
}
void showErrorMsg(String msg) {
Toolkit.getDefaultToolkit().beep();
logger.info(msg);
JOptionPane.showMessageDialog(this, msg, "Error Message",
JOptionPane.ERROR_MESSAGE);
}
boolean confirmed(String title, String msg) {
return JOptionPane.showConfirmDialog(this, msg, title,
JOptionPane.YES_NO_OPTION) == 0;
}
void fireTreeStructureChanged(File file) {
FileTreeModel model = (FileTreeModel) fileTree.getModel();
model.fireStructureChanged(file);
}
void fireTreeStructureChanged(List<File> files) {
for (File file : files) {
fireTreeStructureChanged(file);
}
}
private File getSelectedTreeNode() {
return (File) fileTree.getSelectionPath().getLastPathComponent();
}
private void setSelectedTreeNode(File file) {
TreePath treePath = OS.instance().createTreePath(file);
fileTree.setSelectionPath(treePath);
}
// TODO open multiple files
void open() {
try {
int row = fileTable.getSelectedRow();
if (row != -1) {
FileTableModel model = (FileTableModel) fileTable.getModel();
int modelIndex = fileTable.convertRowIndexToModel(row);
File file = model.getFiles()[modelIndex];
if (OS.instance().doOpen(file)) {
Desktop.getDesktop().open(file);
} else {
setSelectedTreeNode(file);
}
}
} catch (IOException e) {
showErrorMsg(e);
}
}
void delete() {
try {
List<File> files = fileTable.getSelectedTableFiles();
if (files.isEmpty()) {
File file = getSelectedTreeNode();
String msg = "Do you want to delete " + file.getName() + "?";
if (confirmed("Delete", msg)) {
FileManager.delete(file);
setSelectedTreeNode(file.getParentFile());
fireTreeStructureChanged(file);
}
} else {
StringBuilder msg = new StringBuilder();
msg.append("Do you want to delete ");
if (files.size() == 1) {
msg.append(files.get(0).getName());
} else {
msg.append("selected files");
}
msg.append("?");
if (confirmed("Delete", msg.toString())) {
FileManager.delete(files);
fileTable.getFileModel().fireDeleted(files);
fireTreeStructureChanged(files);
}
}
} catch (IOException e) {
showErrorMsg(e);
}
}
void paste() {
try {
ClipboardManager manager = ClipboardManager.instance();
List<File> files = manager.getFileContent();
ClipboardStrategy strategy = manager.getStrategyContent();
if (files == null || files.isEmpty()) {
Toolkit.getDefaultToolkit().beep();
} else {
File destDir = getSelectedTreeNode();
new PasteDialog(this, files, destDir, strategy);
}
} catch (IOException e) {
showErrorMsg(e);
} catch (UnsupportedFlavorException e) {
showErrorMsg(e);
}
}
void copy() {
List<File> files = fileTable.getSelectedTableFiles();
if (!files.isEmpty()) {
ClipboardManager.instance().copy(files);
} else {
Toolkit.getDefaultToolkit().beep();
}
}
void cut() {
List<File> files = fileTable.getSelectedTableFiles();
if (!files.isEmpty()) {
ClipboardManager.instance().cut(files);
} else {
Toolkit.getDefaultToolkit().beep();
}
}
void newFolder() {
File parentDir = getSelectedTreeNode();
File newDir = new File(parentDir, "untitled folder");
if (!newDir.mkdir()) {
showErrorMsg("Couldn't create folder " + newDir);
} else {
fileTable.getFileModel().fireInserted(newDir);
fileTable.editFile(newDir);
}
}
void closeWindow() {
setVisible(false);
}
@Override
public void valueChanged(TreeSelectionEvent e) {
File file = (File) e.getPath().getLastPathComponent();
fileTable.getFileModel().setFile(file);
setTitle(file.getAbsolutePath());
}
@Override
public void mouseClicked(MouseEvent e) {
Component c = e.getComponent();
if (c == fileTable) {
if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON3) {
fileTablePopupMenu.show(e);
} else if (e.getClickCount() == 2) {
open();
}
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
Component c = e.getComponent();
int key = e.getKeyChar();
int keyCode = e.getKeyCode();
if (key == 'v' && e.isMetaDown()) {
paste();
} else if (key == 127 && OS.instance().isMac()) { // apple+backspace
delete();
} else if (c == fileTable) {
if (keyCode == KeyEvent.VK_ENTER) {
open();
} else if (keyCode == KeyEvent.VK_TAB) {
fileTree.requestFocus();
} else if (key == 'c' && e.isMetaDown()) {
copy();
} else if (key == 'x' && e.isMetaDown()) {
cut();
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void windowGainedFocus(WindowEvent e) {
}
@Override
public void windowLostFocus(WindowEvent e) {
fileTablePopupMenu.setVisible(false);
}
}