package view;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JOptionPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import model.Library;
import model.TrackTableModel;
import model.dto.TrackTransferDto;
import view.customs.DropTreeNode;
import view.customs.TreePopupMenu;
import view.views.LibView;
import view.views.PlaylistView;
import view.views.QueueView;
import view.views.TaggerView;
import controller.PhoenixCore;
import controller.interfaces.PhoenixGUI;
/**
* Tree-Anzeige der Bibliothek (Warteschlange, bibliothek, playlists)
*
* @author Artur Dawtjan
*/
@SuppressWarnings("serial")
public class LibTreeView extends JTree implements TreeSelectionListener{
private PhoenixGUI gui;
public LibTreeView itself = this;
private LibView libView = null;
private TrackTable queueTable;
private TreePopupMenu popupMenu = null;
private DefaultMutableTreeNode playlistsNode=null;
private PreparedStatement getAllPlaylistsStmt = null;
public LibTreeView(PhoenixGUI gui) {
super(new DefaultMutableTreeNode());
this.gui = gui;
buildTree();
expandRow(0);
setRootVisible(false);
setShowsRootHandles(true);
addTreeSelectionListener(this);
setSelectionRow(0);
setTransferHandler(new ToTransferHandler(1));
DefaultMutableTreeNode currentNode = ((DefaultMutableTreeNode) getModel()
.getRoot()).getNextNode();
do {
if (currentNode.getLevel() == 1)
expandPath(new TreePath(currentNode.getPath()));
currentNode = currentNode.getNextNode();
} while (currentNode != null);
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
popupMenu.setVisible(false);
if (SwingUtilities.isRightMouseButton(e)) {
Point p = e.getPoint();
TreePath path = itself.getClosestPathForLocation(p.x, p.y);
if (path != null) {
// popup zeigen
itself.setSelectionPath(path);
popupMenu.show(e.getComponent(), p.x, p.y);
}
}
}
});
}
/**
* baut den Baum auf.
*/
private void buildTree() {
DefaultMutableTreeNode node = null;
DefaultMutableTreeNode leaf = null;
DefaultMutableTreeNode top = (DefaultMutableTreeNode) getModel()
.getRoot();
libView = new LibView("Bibliothek", gui.getCore());
node = new DropTreeNode(libView);
top.add(node);
gui.setView(libView);
node = new DropTreeNode(new QueueView("Warteschlange", gui.getCore()),
true);
top.add(node);
queueTable = ((QueueView) node.getUserObject()).getTrackTable();
node = new DropTreeNode("Fehlerhafte Dateien");
top.add(node);
node = new DropTreeNode(new TaggerView("Tagger", gui.getCore()), true);
top.add(node);
node = new DropTreeNode("Wiedergabelisten");
playlistsNode = node;
top.add(node);
popupMenu = new TreePopupMenu(this);
ResultSet rs = null;
try {
getAllPlaylistsStmt = PhoenixCore.DBCON.prepareOnLib("select id, name from playlists order by lower(name) asc");
rs = getAllPlaylistsStmt.executeQuery();
} catch (SQLException e1) {
e1.printStackTrace();
}
try {
while (rs.next()) {
leaf = new DropTreeNode(new PlaylistView(gui.getCore(),rs.getInt("id"), rs.getString("name")), true);
node.add(leaf);
}
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void refreshLibrary(){
libView = new LibView("Bibliothek", PhoenixCore.INSTANCE);
gui.setView(libView);
}
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) getLastSelectedPathComponent();
if (node != null && (node.getUserObject() instanceof view.AbstractView)
&& node.isLeaf()) {
gui.setView(((AbstractView) node.getUserObject()));
}
}
/**
* Handlet einkommende drag-n-drop transfers.
*
* @author Artur Dawtjan
*
*/
class ToTransferHandler extends TransferHandler {
int action;
public ToTransferHandler(int action) {
this.action = action;
}
public boolean canImport(TransferHandler.TransferSupport support) {
// for the demo, we'll only support drops (not clipboard paste)
if (!support.isDrop()) {
return false;
}
JTree.DropLocation dl = (JTree.DropLocation) support
.getDropLocation();
// we only import Strings
try {
if (null == dl.getPath()
|| !((DropTreeNode) dl.getPath().getLastPathComponent())
.canBeDropTarget()
|| !support.isDataFlavorSupported(new DataFlavor(
DataFlavor.javaJVMLocalObjectMimeType
+ ";class=\""
+ TrackTransferDto.class.getName()
+ "\""))) {
return false;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
boolean actionSupported = (action & support.getSourceDropActions()) == action;
if (actionSupported) {
support.setDropAction(action);
return true;
}
return false;
}
public boolean importData(TransferHandler.TransferSupport support) {
// if we can't handle the import, say so
if (!canImport(support)) {
return false;
}
// fetch the drop location
JTree.DropLocation dl = (JTree.DropLocation) support
.getDropLocation();
DropTreeNode dropNode = (DropTreeNode) dl.getPath()
.getLastPathComponent();
// fetch the data and bail if this fails
TrackTransferDto data;
try {
data = (TrackTransferDto) support.getTransferable()
.getTransferData(
new DataFlavor(
DataFlavor.javaJVMLocalObjectMimeType
+ ";class=\""
+ TrackTransferDto.class
.getName() + "\""));
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
return false;
} catch (java.io.IOException e) {
e.printStackTrace();
return false;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return false;
}
((AbstractView) dropNode.getUserObject()).addTracks(data
.getTracks());
return false;// false, damit wieder zur urspruenglichen view
// gesprungen wird.
}
}
public Library getQueue() {
return ((TrackTableModel) queueTable.getModel()).getLib();
}
public void updateQueueView() {
((TrackTableModel) queueTable.getModel()).fireTableDataChanged();
}
/**
* im kontextmenü wurde "neue playlist anlegen" ausgwählt.
*/
public void addPlaylist(){
String input = JOptionPane.showInputDialog("Wie soll der Name der neuen Playlist lauten?");
if ("".equals(input)) {//leer?
JOptionPane.showMessageDialog(null, "Kein Name eingegeben!", "Operation Abgebrochen", JOptionPane.INFORMATION_MESSAGE);
}else if (input == null) {//abbruch?
return;
}else if (!isValidPlaylistName(input)) {//sonderzeichen?
JOptionPane.showMessageDialog(null, "Sonderzeichen sind nicht erlaubt.", "Operation Abgebrochen", JOptionPane.INFORMATION_MESSAGE);
}else{//gültig, also:
PreparedStatement insertPlaylistStmt=null;
int newListID =0;
try {
insertPlaylistStmt = PhoenixCore.DBCON.prepareOnLib("insert into playlists (id, name) values (null, ?)");
insertPlaylistStmt.setString(1, input);
insertPlaylistStmt.executeUpdate();
ResultSet rs = insertPlaylistStmt.getGeneratedKeys();
if (rs.next()) {
newListID = rs.getInt(1);
}
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
DropTreeNode node = new DropTreeNode(new PlaylistView(gui.getCore(),newListID, input), true);
((DefaultTreeModel)getModel()).insertNodeInto(node, playlistsNode, playlistsNode.getChildCount());
setSelectionPath(new TreePath(node.getPath()));
setSelectionRow(0);
}
}
private boolean isValidPlaylistName(String s){
char chars[] = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (!Character.isLetterOrDigit(chars[i])&&!Character.isWhitespace(chars[i])){
return false;
}
}
return true;
}
public void deletePlaylist() {
DefaultMutableTreeNode node = ((DefaultMutableTreeNode)getLastSelectedPathComponent());
PlaylistView pl = ((PlaylistView)node.getUserObject());
int id = pl.getPlaylistID();
if (JOptionPane.YES_OPTION==JOptionPane.showConfirmDialog(null, "Soll die Playlist \""+pl.getPlaylistName()+"\" wirklich gelöscht werden?", "Sicher?", JOptionPane.YES_NO_OPTION)) {
PhoenixCore.DBCON.deleteOnLib("delete from playlist_track where listid="+id);
PhoenixCore.DBCON.deleteOnLib("delete from playlists where id="+id);
((DefaultTreeModel)getModel()).removeNodeFromParent(node);
setSelectionRow(0);
}
}
public void renamePlaylist() {
String input = JOptionPane.showInputDialog("Wie soll der neue Name der Playlist lauten?");
if ("".equals(input)) {//leer?
JOptionPane.showMessageDialog(null, "Kein Name eingegeben!", "Operation Abgebrochen", JOptionPane.INFORMATION_MESSAGE);
}else if (input == null) {//abbruch?
return;
}else if (!isValidPlaylistName(input)) {//sonderzeichen?
JOptionPane.showMessageDialog(null, "Sonderzeichen sind nicht erlaubt.", "Operation Abgebrochen", JOptionPane.INFORMATION_MESSAGE);
}else{//gültig, also:
DropTreeNode node = ((DropTreeNode)getLastSelectedPathComponent());
PlaylistView pl = ((PlaylistView)node.getUserObject());
int id = pl.getPlaylistID();
PhoenixCore.DBCON.deleteOnLib("update playlists set name='"+input+"' where id="+id);
pl.setPlaylistName(input);
node.setUserObject(pl);
((DefaultTreeModel)getModel()).nodeChanged(node);
}
}
}