diff --git a/Mage.Client/src/main/java/mage/client/components/ColorPane.java b/Mage.Client/src/main/java/mage/client/components/ColorPane.java
index 370459a2664..aa6d5be1aac 100644
--- a/Mage.Client/src/main/java/mage/client/components/ColorPane.java
+++ b/Mage.Client/src/main/java/mage/client/components/ColorPane.java
@@ -2,13 +2,28 @@ package mage.client.components;
import java.awt.BorderLayout;
import java.awt.Color;
+import java.awt.Component;
import java.awt.Graphics;
+import java.awt.Point;
+
import javax.swing.JEditorPane;
import javax.swing.JPanel;
import javax.swing.JTextPane;
+import javax.swing.SwingUtilities;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkEvent.EventType;
+import javax.swing.event.HyperlinkListener;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
+import mage.cards.repository.CardInfo;
+import mage.cards.repository.CardRepository;
+import mage.client.MageFrame;
+import mage.client.dialog.PreferencesDialog;
+import mage.client.util.gui.GuiDisplayUtil;
+import mage.components.CardInfoPane;
+import mage.view.CardView;
+
/**
* Enhanced {@link JTextPane} with text highlighting support.
*
@@ -18,10 +33,52 @@ public class ColorPane extends JEditorPane {
HTMLEditorKit kit = new HTMLEditorKit();
HTMLDocument doc = new HTMLDocument();
+ private int tooltipDelay;
public ColorPane() {
this.setEditorKit(kit);
this.setDocument(doc);
+ addHyperlinkListener(new HyperlinkListener() {
+
+ @Override
+ public void hyperlinkUpdate(final HyperlinkEvent e) {
+ tooltipDelay = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300);
+ if (tooltipDelay == 0) {
+ return;
+ }
+ String name = e.getDescription().substring(1);
+ CardInfo card = CardRepository.instance.findCard(name);
+ try {
+ final Component container = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER);
+ if (e.getEventType() == EventType.EXITED) {
+ setPopupVisibility(container, false);
+ } else {
+ CardInfoPane cardInfoPane = (CardInfoPane) MageFrame.getUI().getComponent(MageComponents.CARD_INFO_PANE);
+ cardInfoPane.setCard(new CardView(card.getMockCard()), container);
+ Point location = new Point(getLocationOnScreen().x - container.getWidth(), (int) MageFrame.getDesktop()
+ .getMousePosition().getY());
+ Component parentComponent = MageFrame.getInstance();
+ location = GuiDisplayUtil.keepComponentInsideParent(location, parentComponent.getLocationOnScreen(), container,
+ parentComponent);
+ container.setLocation(location);
+ setPopupVisibility(container, true);
+ }
+ } catch (InterruptedException e1) {
+ e1.printStackTrace();
+ }
+ }
+
+ private void setPopupVisibility(final Component container, final boolean show) throws InterruptedException {
+ final Component c = MageFrame.getUI().getComponent(MageComponents.DESKTOP_PANE);
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ container.setVisible(show);
+ c.repaint();
+ }
+ });
+ }
+ });
}
/**
@@ -45,6 +102,7 @@ public class ColorPane extends JEditorPane {
public void append(String text) {
try {
+ text = text.replaceAll("(]*>([^<]*)) (\\[[0-9a-fA-F]*\\])", "$1 $3");
setEditable(true);
kit.insertHTML(doc, doc.getLength(), text, 0, 0, null);
setEditable(false);
diff --git a/Mage.Client/src/main/java/mage/client/components/ability/AbilityPicker.java b/Mage.Client/src/main/java/mage/client/components/ability/AbilityPicker.java
index efed293521b..5d46d46db97 100644
--- a/Mage.Client/src/main/java/mage/client/components/ability/AbilityPicker.java
+++ b/Mage.Client/src/main/java/mage/client/components/ability/AbilityPicker.java
@@ -14,6 +14,7 @@ import org.apache.log4j.Logger;
import org.jdesktop.layout.GroupLayout;
import org.jdesktop.layout.LayoutStyle;
import org.jdesktop.swingx.JXPanel;
+import org.jsoup.Jsoup;
import org.mage.card.arcane.ManaSymbols;
import org.mage.card.arcane.UI;
@@ -434,6 +435,7 @@ public class AbilityPicker extends JXPanel implements MouseWheelListener {
if (choice == null || choice.isEmpty()) {
return choice;
}
+ choice = Jsoup.parse(choice).text(); // decode HTML entities and strip tags
return choice.substring(0, 1).toUpperCase() + choice.substring(1);
}
diff --git a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java
index 67429dd5e8c..cb63a4d543a 100644
--- a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java
+++ b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java
@@ -54,6 +54,14 @@ import mage.util.TournamentUtil;
*/
public class DeckGenerator {
+ public static class DeckGeneratorException extends RuntimeException {
+
+ public DeckGeneratorException(String message) {
+ super(message);
+ }
+
+ }
+
private static final int MAX_TRIES = 8196;
private static DeckGeneratorDialog genDialog;
private static DeckGeneratorPool genPool;
@@ -82,6 +90,9 @@ public class DeckGenerator {
String format = genDialog.getSelectedFormat();
List setsToUse = ConstructedFormats.getSetsByFormat(format);
+ if (setsToUse == null) {
+ throw new DeckGeneratorException("Deck sets aren't initialized; please connect to a server to update the database.");
+ }
if (setsToUse.isEmpty()) {
// Default to using all sets
setsToUse = ExpansionRepository.instance.getSetCodes();
diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.form b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.form
index 30eac766e46..f0db80d7055 100644
--- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.form
+++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.form
@@ -83,6 +83,8 @@
+
+
@@ -110,6 +112,7 @@
+
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 377b69adda8..d9be9c4e207 100644
--- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java
+++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java
@@ -60,9 +60,9 @@ import mage.client.MageFrame;
import mage.client.cards.BigCard;
import mage.client.cards.ICardGrid;
import mage.client.constants.Constants.DeckEditorMode;
-import static mage.client.constants.Constants.DeckEditorMode.FREE_BUILDING;
-import static mage.client.constants.Constants.DeckEditorMode.LIMITED_BUILDING;
-import static mage.client.constants.Constants.DeckEditorMode.SIDEBOARDING;
+import mage.client.deck.generator.DeckGenerator;
+import mage.client.deck.generator.DeckGenerator.DeckGeneratorException;
+
import mage.client.dialog.AddLandDialog;
import mage.client.plugins.impl.Plugins;
import mage.client.util.Event;
@@ -173,6 +173,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
this.cardSelector.switchToGrid();
this.btnExit.setVisible(false);
this.btnImport.setVisible(false);
+ this.btnGenDeck.setVisible(false);
if (!MageFrame.getSession().isTestMode()) {
this.btnLoad.setVisible(false);
}
@@ -195,6 +196,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
//this.cardTableSelector.loadCards(this.bigCard);
this.btnExit.setVisible(true);
this.btnImport.setVisible(true);
+ this.btnGenDeck.setVisible(true);
if (!MageFrame.getSession().isTestMode()) {
this.btnLoad.setVisible(true);
}
@@ -504,6 +506,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
btnImport = new javax.swing.JButton();
btnSubmit = new javax.swing.JButton();
btnAddLand = new javax.swing.JButton();
+ btnGenDeck = new javax.swing.JButton();
txtTimeRemaining = new javax.swing.JTextField();
jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
@@ -591,6 +594,15 @@ public class DeckEditorPanel extends javax.swing.JPanel {
btnAddLandActionPerformed(evt);
}
});
+
+ btnGenDeck.setText("Generate");
+ btnGenDeck.setName("btnGenDeck");
+ btnGenDeck.addActionListener(new java.awt.event.ActionListener() {
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnGenDeckActionPerformed(evt);
+ }
+ });
txtTimeRemaining.setEditable(false);
txtTimeRemaining.setForeground(java.awt.Color.red);
@@ -626,6 +638,8 @@ public class DeckEditorPanel extends javax.swing.JPanel {
.addContainerGap()
.addComponent(btnImport)
.addContainerGap()
+ .addComponent(btnGenDeck)
+ .addContainerGap()
.addComponent(btnAddLand)
.addContainerGap()
.addComponent(btnSubmit))
@@ -650,6 +664,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnImport)
+ .addComponent(btnGenDeck)
.addComponent(btnAddLand)
.addComponent(btnSubmit))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@@ -801,6 +816,21 @@ public class DeckEditorPanel extends javax.swing.JPanel {
refreshDeck();
}//GEN-LAST:event_btnAddLandActionPerformed
+ private void btnGenDeckActionPerformed(ActionEvent evt) {
+ try {
+ setCursor(new Cursor(Cursor.WAIT_CURSOR));
+ String path = DeckGenerator.generateDeck();
+ deck = Deck.load(DeckImporterUtil.importDeck(path), true, true);
+ } catch (GameException ex) {
+ JOptionPane.showMessageDialog(MageFrame.getDesktop(), ex.getMessage(), "Error loading generated deck", JOptionPane.ERROR_MESSAGE);
+ }catch (DeckGeneratorException ex) {
+ JOptionPane.showMessageDialog(MageFrame.getDesktop(), ex.getMessage(), "Generator error", JOptionPane.ERROR_MESSAGE);
+ } finally {
+ setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+ }
+ refreshDeck();
+ }
+
// Variables declaration - do not modify//GEN-BEGIN:variables
private mage.client.cards.BigCard bigCard;
private javax.swing.JButton btnExit;
@@ -816,6 +846,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
private javax.swing.JTextField txtDeckName;
private javax.swing.JButton btnSubmit;
private javax.swing.JButton btnAddLand;
+ private javax.swing.JButton btnGenDeck;
private JComponent cardInfoPane;
private javax.swing.JTextField txtTimeRemaining;
// End of variables declaration//GEN-END:variables
diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
index 9a59abd1730..6436e0172bd 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
@@ -66,6 +66,7 @@ import static mage.client.dialog.PreferencesDialog.KEY_CONNECT_FLAG;
import mage.client.preference.MagePreferences;
import mage.client.util.Config;
import mage.client.util.gui.countryBox.CountryItemEditor;
+import mage.client.util.sets.ConstructedFormats;
import mage.remote.Connection;
import org.apache.log4j.Logger;
@@ -442,6 +443,7 @@ public class ConnectDialog extends MageDialog {
private void connected() {
this.saveSettings();
this.hideDialog();
+ ConstructedFormats.ensureLists();
}
private void keyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_keyTyped
diff --git a/Mage.Client/src/main/java/mage/client/util/sets/ConstructedFormats.java b/Mage.Client/src/main/java/mage/client/util/sets/ConstructedFormats.java
index 81bc28210b6..f76efc4af01 100644
--- a/Mage.Client/src/main/java/mage/client/util/sets/ConstructedFormats.java
+++ b/Mage.Client/src/main/java/mage/client/util/sets/ConstructedFormats.java
@@ -50,6 +50,12 @@ public class ConstructedFormats {
}
+ public static void ensureLists() {
+ if (getSetsByFormat(ConstructedFormats.STANDARD) == null) {
+ buildLists();
+ }
+ }
+
private static void buildLists() {
GregorianCalendar cutoff;
// month is zero based so January = 0
@@ -60,6 +66,7 @@ public class ConstructedFormats {
cutoff = new GregorianCalendar(calendar.get(Calendar.YEAR) - 2, Calendar.SEPTEMBER, 1);
}
final Map expansionInfo = new HashMap<>();
+ formats.clear(); // prevent NPE on sorting if this is not the first try
for (ExpansionInfo set : ExpansionRepository.instance.getAll()) {
expansionInfo.put(set.getName(), set);
formats.add(set.getName());
@@ -207,10 +214,11 @@ public class ConstructedFormats {
}
});
-
- formats.add(0, MODERN);
- formats.add(0, EXTENDED);
- formats.add(0, STANDARD);
+ if (!formats.isEmpty()) {
+ formats.add(0, MODERN);
+ formats.add(0, EXTENDED);
+ formats.add(0, STANDARD);
+ }
formats.add(0, ALL);
}
diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java b/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java
index 7e76349d6ad..0df1894a878 100644
--- a/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java
+++ b/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java
@@ -31,6 +31,7 @@ import net.xeoh.plugins.base.annotations.meta.Author;
import org.apache.log4j.Logger;
import org.mage.card.arcane.Animation;
import org.mage.card.arcane.CardPanel;
+import org.mage.card.arcane.ManaSymbols;
import org.mage.plugins.card.dl.DownloadGui;
import org.mage.plugins.card.dl.DownloadJob;
import org.mage.plugins.card.dl.Downloader;
@@ -540,6 +541,7 @@ public class CardPluginImpl implements CardPlugin {
@Override
public void windowClosing(WindowEvent e) {
g.getDownloader().dispose();
+ ManaSymbols.loadImages();
}
});
d.setLayout(new BorderLayout());