diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java index 88b3cc0d95..d79cebb6cc 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -4,6 +4,7 @@ import mage.cards.Card; import mage.cards.Sets; import mage.cards.decks.Deck; import mage.cards.decks.DeckCardLists; +import mage.cards.decks.DnDDeckTargetListener; import mage.cards.decks.importer.DeckImporter; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; @@ -30,11 +31,13 @@ import org.apache.log4j.Logger; import javax.swing.*; import javax.swing.filechooser.FileFilter; import java.awt.*; +import java.awt.dnd.DropTarget; import java.awt.event.*; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.*; +import java.util.List; import java.util.concurrent.*; /** @@ -445,6 +448,16 @@ public class DeckEditorPanel extends javax.swing.JPanel { }); refreshDeck(); + if (mode == DeckEditorMode.FREE_BUILDING) { + setDropTarget(new DropTarget(this, new DnDDeckTargetListener() { + @Override + protected boolean handleFilesDrop(boolean move, List files) { + loadDeck(files.get(0).getAbsolutePath()); + return true; + } + })); + } + this.setVisible(true); this.repaint(); } @@ -785,6 +798,29 @@ public class DeckEditorPanel extends javax.swing.JPanel { } } + private boolean loadDeck(String file) { + Deck newDeck = null; + StringBuilder errorMessages = new StringBuilder(); + + MageFrame.getDesktop().setCursor(new Cursor(Cursor.WAIT_CURSOR)); + try { + newDeck = Deck.load(DeckImporter.importDeckFromFile(file, errorMessages), true, true); + processAndShowImportErrors(errorMessages); + + if (newDeck != null) { + deck = newDeck; + refreshDeck(); + return true; + } + + } catch (GameException e1) { + JOptionPane.showMessageDialog(MageFrame.getDesktop(), e1.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE); + } finally { + MageFrame.getDesktop().setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + } + return false; + } + /** * @param evt ActionEvent */ @@ -796,24 +832,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { dialog.addWindowListener(new WindowAdapter() { @Override public void windowClosed(WindowEvent e) { - Deck newDeck = null; - StringBuilder errorMessages = new StringBuilder(); - - MageFrame.getDesktop().setCursor(new Cursor(Cursor.WAIT_CURSOR)); - try { - newDeck = Deck.load(DeckImporter.importDeckFromFile(dialog.getTmpPath(), errorMessages), true, true); - processAndShowImportErrors(errorMessages); - - if (newDeck != null) { - deck = newDeck; - refreshDeck(); - } - - } catch (GameException e1) { - JOptionPane.showMessageDialog(MageFrame.getDesktop(), e1.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE); - } finally { - MageFrame.getDesktop().setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); - } + loadDeck(dialog.getTmpPath()); } }); } diff --git a/Mage/src/main/java/mage/cards/decks/DnDDeckTargetListener.java b/Mage/src/main/java/mage/cards/decks/DnDDeckTargetListener.java new file mode 100644 index 0000000000..5103de77a1 --- /dev/null +++ b/Mage/src/main/java/mage/cards/decks/DnDDeckTargetListener.java @@ -0,0 +1,109 @@ +package mage.cards.decks; + +import javax.swing.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +public class DnDDeckTargetListener extends DropTargetAdapter { + + private static final DataFlavor fileFlavor = DataFlavor.javaFileListFlavor; + private static final DataFlavor plainTextFlavor = DataFlavor.stringFlavor; + + private boolean isCopyOrMove(int dropAction) { + return (dropAction & TransferHandler.COPY_OR_MOVE) != 0; + } + + private boolean isCopyAction(int dropAction) { + return (dropAction & TransferHandler.COPY) != 0; + } + + private boolean isMoveAction(int dropAction) { + return (dropAction & TransferHandler.MOVE) != 0; + } + + private boolean isAcceptable(DropTargetDragEvent dtde) { + boolean copyOrMove = isCopyOrMove(dtde.getDropAction()); + boolean flavorSupported = dtde.isDataFlavorSupported(plainTextFlavor) || dtde.isDataFlavorSupported(fileFlavor); + return copyOrMove && flavorSupported; + } + + @Override + public void dragEnter(DropTargetDragEvent dtde) { + if (isAcceptable(dtde)) { + dtde.acceptDrag(TransferHandler.COPY); + } else { + dtde.rejectDrag(); + } + } + + @Override + public void dragOver(DropTargetDragEvent dtde) { + if (isAcceptable(dtde)) { + dtde.acceptDrag(TransferHandler.COPY); + } else { + dtde.rejectDrag(); + } + } + + @Override + public void dropActionChanged(DropTargetDragEvent dtde) { + if (isAcceptable(dtde)) { + dtde.acceptDrag(TransferHandler.COPY); + } else { + dtde.rejectDrag(); + } + } + + @Override + public void drop(DropTargetDropEvent dtde) { + if (isCopyOrMove(dtde.getDropAction()) && dtde.isDataFlavorSupported(fileFlavor)) { + dtde.acceptDrop(TransferHandler.COPY); + } else if (isCopyOrMove(dtde.getDropAction()) && dtde.isDataFlavorSupported(plainTextFlavor)) { + dtde.acceptDrop(TransferHandler.COPY); + } else { + dtde.rejectDrop(); + dtde.dropComplete(false); + return; + } + + boolean move = isMoveAction(dtde.getDropAction()); + + try { + if (dtde.isDataFlavorSupported(fileFlavor)) { + List files = (List) dtde.getTransferable().getTransferData(fileFlavor); + dtde.dropComplete(handleFilesDrop(move, files)); + } else if (dtde.isDataFlavorSupported(plainTextFlavor)) { + String text = (String) dtde.getTransferable().getTransferData(plainTextFlavor); + try { + dtde.dropComplete(handleUriDrop(move, new URI(text))); + } catch (URISyntaxException e) { + dtde.dropComplete(handlePlainTextDrop(move, text)); + } + } + } catch (UnsupportedFlavorException | IOException e) { + e.printStackTrace(); + dtde.dropComplete(false); + } + } + + protected boolean handlePlainTextDrop(boolean move, String text) { + return false; + } + + protected boolean handleUriDrop(boolean move, URI uri) { + return false; + } + + protected boolean handleFilesDrop(boolean move, List files) { + return false; + } + +}