Update card image downloading (see #1039).

master
lodici 2017-02-20 20:59:08 +00:00
parent 4a93805b00
commit f48e2c9740
17 changed files with 497 additions and 273 deletions

View File

@ -14,6 +14,11 @@ import org.apache.commons.io.FileUtils;
public class DownloadableFile {
private static final GeneralConfig CONFIG = GeneralConfig.getInstance();
private static String proxySettings = "";
private static Proxy proxy = Proxy.NO_PROXY;
private final File localFile;
private final URL remoteFile;
@ -34,24 +39,24 @@ public class DownloadableFile {
return localFile.getName();
}
public void doDownload(final Proxy proxy) throws IOException {
public void doDownload() throws IOException {
final File tempFile = new File(localFile.getParent(), "~" + localFile.getName());
downloadToFile(proxy, remoteFile, tempFile);
downloadToFile(remoteFile, tempFile);
Files.move(tempFile.toPath(), localFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
public static void downloadToFile(final Proxy proxy, final URL url, final File file) throws IOException {
if (proxy != Proxy.NO_PROXY && proxy.type() != Proxy.Type.DIRECT) {
downloadUsingProxy(proxy, url, file);
} else {
FileUtils.copyURLToFile(url, file, 10000, 5000);
private static Proxy getProxy() {
if (!proxySettings.equals(CONFIG.getProxySettings())) {
proxySettings = CONFIG.getProxySettings();
proxy = CONFIG.getProxy();
}
return proxy;
}
private static void downloadUsingProxy(final Proxy proxy, final URL url, final File file) throws IOException {
private static void downloadUsingProxy(URL url, File file) throws IOException {
try (
final OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file));
final InputStream inputStream = url.openConnection(proxy).getInputStream()) {
final InputStream inputStream = url.openConnection(getProxy()).getInputStream()) {
final byte[] buffer = new byte[65536];
while (true) {
final int len = inputStream.read(buffer);
@ -66,4 +71,12 @@ public class DownloadableFile {
}
}
public static void downloadToFile(URL url, File file) throws IOException {
if (getProxy() != Proxy.NO_PROXY && getProxy().type() != Proxy.Type.DIRECT) {
downloadUsingProxy(url, file);
} else {
FileUtils.copyURLToFile(url, file, 10000, 5000);
}
}
}

View File

@ -190,15 +190,13 @@ public class GeneralConfig {
public Proxy getProxy() {
final String DELIM = "\\|";
final String proxyString = proxySettings.trim();
if (proxyString.isEmpty() || proxyString.split(DELIM).length != 3) {
return Proxy.NO_PROXY;
} else {
final Proxy.Type proxyType = Proxy.Type.valueOf(proxyString.split(DELIM)[0]);
final int port = Integer.parseInt(proxyString.split(DELIM)[1]);
final String urlAddress = proxyString.split(DELIM)[2];
if (!proxySettings.isEmpty() && proxySettings.split(DELIM).length == 3) {
Proxy.Type proxyType = Proxy.Type.valueOf(proxySettings.split(DELIM)[0]);
int port = Integer.parseInt(proxySettings.split(DELIM)[1]);
String urlAddress = proxySettings.split(DELIM)[2];
return new Proxy(proxyType, new InetSocketAddress(urlAddress, port));
}
return Proxy.NO_PROXY;
}
public void setProxy(final Proxy proxy) {
@ -214,6 +212,10 @@ public class GeneralConfig {
}
}
public String getProxySettings() {
return proxySettings;
}
public int getDeckFileMaxLines() {
return deckFileMaxLines;
}
@ -559,7 +561,7 @@ public class GeneralConfig {
cardImagesPath = properties.getProperty(CARD_IMAGES_PATH, cardImagesPath);
animateGameplay = Boolean.parseBoolean(properties.getProperty(ANIMATE_GAMEPLAY, "" + animateGameplay));
deckFileMaxLines = Integer.parseInt(properties.getProperty(DECK_FILE_MAX_LINES, ""+ deckFileMaxLines));
proxySettings = properties.getProperty(PROXY_SETTINGS, proxySettings);
proxySettings = properties.getProperty(PROXY_SETTINGS, proxySettings).trim();
firemindAccessToken = properties.getProperty(FIREMIND_ACCESS_TOKEN, firemindAccessToken);
newTurnAlertDuration = Integer.parseInt(properties.getProperty(NEWTURN_ALERT_DURATION,"" + newTurnAlertDuration));
landPreviewDuration = Integer.parseInt(properties.getProperty(LAND_PREVIEW_DURATION,"" + landPreviewDuration));

View File

@ -2,7 +2,6 @@ package magic.data.json;
import java.io.File;
import java.io.IOException;
import magic.data.GeneralConfig;
import magic.utility.MagicFileSystem;
import magic.utility.MagicFileSystem.DataPath;
import magic.utility.MagicSystem;
@ -23,7 +22,7 @@ public final class NewVersionJsonParser {
private static boolean downloadJsonToFile(final File jsonFile) {
try {
final DownloadableJsonFile downloadFile = new DownloadableJsonFile("https://magarena.github.io/current.json", jsonFile);
downloadFile.doDownload(GeneralConfig.getInstance().getProxy());
downloadFile.doDownload();
if (jsonFile.length() == 0) {
System.err.println("new version json file is empty!");
return false;

View File

@ -0,0 +1,23 @@
package magic.exception;
import magic.data.DownloadableFile;
@SuppressWarnings("serial")
public class DownloadException extends Exception {
private final DownloadableFile dfile;
public DownloadException(String message, Throwable cause, final DownloadableFile dfile) {
super(message, cause);
this.dfile = dfile;
}
public DownloadException(String message, Throwable cause) {
super(message, cause);
this.dfile = null;
}
public boolean hasFile() {
return dfile != null;
}
}

View File

@ -6,7 +6,6 @@ import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import magic.data.GeneralConfig;
import magic.data.json.DownloadableJsonFile;
import magic.model.MagicDeck;
import magic.utility.DeckUtils;
@ -30,7 +29,7 @@ public final class FiremindJsonReader {
try {
final DownloadableJsonFile downloadFile =
new DownloadableJsonFile("https://www.firemind.ch/decks/top.json", jsonFile);
downloadFile.doDownload(GeneralConfig.getInstance().getProxy());
downloadFile.doDownload();
} catch (IOException ex) {
System.err.println("Download of json file failed : " + ex.getMessage());
}

View File

@ -2,13 +2,12 @@ package magic.ui;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.Proxy;
import java.nio.file.Path;
import java.util.Arrays;
import magic.cardBuilder.renderers.CardBuilder;
import magic.data.CardImageFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import magic.data.GeneralConfig;
import magic.exception.DownloadException;
import magic.model.IRenderableCard;
import magic.model.MagicCardDefinition;
import magic.ui.screen.images.download.CardImageDisplayMode;
@ -26,17 +25,18 @@ public final class MagicCardImages {
PRINTED
}
private static final Logger LOGGER = Logger.getLogger(MagicCardImages.class.getName());
private static final String[] CUSTOM_IMAGE_ENDINGS = new String[]{".jpg", ".full.jpg"};
private static final GeneralConfig CONFIG = GeneralConfig.getInstance();
private static Proxy proxy;
private static File getCustomCardImageFile(IRenderableCard face, String ending) {
Path imagesFolder = MagicFileSystem.getImagesPath(MagicFileSystem.ImagesPath.CUSTOM);
return new File(imagesFolder.toFile(), face.getImageName() + ending);
}
private static boolean customCardImageExists(IRenderableCard face) {
public static boolean isCustomCardImageFound(IRenderableCard face) {
return Arrays.stream(CUSTOM_IMAGE_ENDINGS)
.anyMatch(ending -> getCustomCardImageFile(face, ending).exists());
}
@ -50,21 +50,26 @@ public final class MagicCardImages {
.orElse(MagicImages.MISSING_CARD);
}
private static boolean printedImageExists(IRenderableCard face) {
return MagicFileSystem.getPrintedCardImage(face).exists();
}
private static ImageType getImageType(IRenderableCard face) {
if (face.isUnknown()) {
return ImageType.UNKNOWN;
}
if (customCardImageExists(face)) {
if (isCustomCardImageFound(face)) {
return ImageType.CUSTOM;
}
if (CONFIG.getCardImageDisplayMode() == CardImageDisplayMode.PROXY) {
if (CONFIG.getCardImageDisplayMode() == CardImageDisplayMode.PROXY
&& !face.isPlaneswalker() && !face.isFlipCard() && !face.isToken()) {
return ImageType.PROXY;
}
if (MagicFileSystem.getPrintedCardImage(face).exists() || CONFIG.getImagesOnDemand()) {
if (printedImageExists(face) || CONFIG.getImagesOnDemand()) {
return ImageType.PRINTED;
}
@ -72,53 +77,60 @@ public final class MagicCardImages {
return ImageType.PROXY;
}
private static void tryDownloadingPrintedImage(IRenderableCard face) {
if (proxy == null) {
proxy = CONFIG.getProxy();
}
private static BufferedImage getPrintedCardImage(IRenderableCard face) {
try {
CardImageFile cif = new CardImageFile(face);
cif.doDownload(proxy);
} catch (IOException ex) {
System.err.println(face.getCardDefinition().getDistinctName() + " : " + ex);
return PrintedCardImage.get(face);
} catch (DownloadException ex) {
LOGGER.log(Level.SEVERE, null, ex);
return MagicImages.MISSING_CARD;
}
}
private static BufferedImage getProxyCardImage(IRenderableCard face) {
try {
return ProxyCardImage.get(face);
} catch (DownloadException ex) {
LOGGER.log(Level.SEVERE, null, ex);
return MagicImages.MISSING_CARD;
}
}
public static BufferedImage createImage(IRenderableCard face) {
final ImageType type = getImageType(face);
switch (type) {
case UNKNOWN:
return MagicImages.MISSING_CARD;
case CUSTOM:
return getCustomCardImage(face);
case PROXY:
return CardBuilder.getCardBuilderImage(face);
case PRINTED:
if (!MagicFileSystem.getPrintedCardImage(face).exists()) {
// on-demand image download.
tryDownloadingPrintedImage(face);
}
if (MagicFileSystem.getPrintedCardImage(face).exists()) {
if (CONFIG.getCardImageDisplayMode() == CardImageDisplayMode.PRINTED || CONFIG.getCardTextLanguage() != CardTextLanguage.ENGLISH) {
return ImageFileIO.getOptimizedImage(MagicFileSystem.getPrintedCardImage(face));
} else {
return face.isPlaneswalker() || face.isFlipCard() || face.isToken()
? ImageFileIO.getOptimizedImage(MagicFileSystem.getPrintedCardImage(face))
: CardBuilder.getCardBuilderImage(face);
}
}
case UNKNOWN: return MagicImages.MISSING_CARD;
case CUSTOM: return getCustomCardImage(face);
case PROXY: return getProxyCardImage(face);
case PRINTED: return getPrintedCardImage(face);
}
return CardBuilder.getCardBuilderImage(face);
throw new RuntimeException("Unsupported image type: " + type);
}
public static boolean isProxyImage(IRenderableCard face) {
return getImageType(face) == ImageType.PROXY;
}
public static boolean isPrintedCardImageMissing(MagicCardDefinition card) {
return !MagicFileSystem.getPrintedCardImage(card).exists();
}
private static boolean customCardImageMissing(MagicCardDefinition card) {
return !isCustomCardImageFound(card);
}
public static boolean isCroppedCardImageMissing(MagicCardDefinition card) {
return !MagicFileSystem.getCroppedCardImage(card).exists();
}
public static boolean isCardImageMissing(MagicCardDefinition aCard) {
return !customCardImageExists(aCard)
&& !MagicFileSystem.getCroppedCardImage(aCard).exists()
&& !MagicFileSystem.getPrintedCardImage(aCard).exists();
if (CONFIG.getCardImageDisplayMode() == CardImageDisplayMode.PRINTED) {
return customCardImageMissing(aCard)
&& isPrintedCardImageMissing(aCard);
} else { // PROXY
return customCardImageMissing(aCard)
&& isCroppedCardImageMissing(aCard)
&& isPrintedCardImageMissing(aCard);
}
}
private MagicCardImages() {}

View File

@ -0,0 +1,73 @@
package magic.ui;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import magic.cardBuilder.renderers.CardBuilder;
import magic.data.CardImageFile;
import magic.data.DownloadableFile;
import magic.data.GeneralConfig;
import magic.exception.DownloadException;
import magic.model.IRenderableCard;
import magic.ui.helpers.UrlHelper;
import magic.utility.MagicFileSystem;
public abstract class PrintedCardImage {
private static final GeneralConfig CONFIG = GeneralConfig.getInstance();
public static boolean imageExists(IRenderableCard face) {
return MagicFileSystem.getPrintedCardImage(face).exists();
}
private static void downloadEnglishImage(CardImageFile aFile) throws DownloadException {
try {
aFile.doDownload();
} catch (IOException ex) {
throw new DownloadException(String.format("%s [%s]", ex.toString(), aFile.getFilename()), ex, aFile);
}
}
private static boolean downloadNonEnglishImage(CardImageFile aFile, CardTextLanguage aLang) throws DownloadException, MalformedURLException {
URL url = UrlHelper.getAltMagicCardsInfoUrl(aFile, aLang);
if (UrlHelper.isUrlValid(url)) {
DownloadableFile df = new DownloadableFile(aFile.getLocalFile(), url);
try {
df.doDownload();
return true;
} catch (IOException ex) {
throw new DownloadException(String.format("%s [%s (%s)]", ex.toString(), aFile.getFilename(), aLang), ex, aFile);
}
}
return false;
}
public static void tryDownloadingPrintedImage(CardImageFile imageFile) throws DownloadException {
try {
CardTextLanguage textLang = GeneralConfig.getInstance().getCardTextLanguage();
if (textLang.isEnglish() || !downloadNonEnglishImage(imageFile, textLang)) {
downloadEnglishImage(imageFile);
}
} catch (MalformedURLException ex) {
throw new DownloadException(String.format("%s [%s]", ex.toString(), imageFile.getUrl()), ex, imageFile);
}
}
private static void tryDownloadingPrintedImage(IRenderableCard face) throws DownloadException {
if (CONFIG.getImagesOnDemand() && !imageExists(face)) {
try {
tryDownloadingPrintedImage(new CardImageFile(face));
} catch (MalformedURLException ex) {
throw new DownloadException(String.format("%s [%s]", ex.toString(), face.getImageName()), ex);
}
}
}
static BufferedImage get(IRenderableCard face) throws DownloadException {
tryDownloadingPrintedImage(face);
return imageExists(face)
? ImageFileIO.getOptimizedImage(MagicFileSystem.getPrintedCardImage(face))
: CardBuilder.getCardBuilderImage(face);
}
}

View File

@ -0,0 +1,68 @@
package magic.ui;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import magic.cardBuilder.renderers.CardBuilder;
import magic.data.CardImageFile;
import magic.data.DownloadableFile;
import magic.data.GeneralConfig;
import magic.exception.DownloadException;
import magic.model.IRenderableCard;
import magic.model.MagicCardDefinition;
import magic.ui.helpers.UrlHelper;
import magic.utility.MagicFileSystem;
public abstract class ProxyCardImage {
private static final GeneralConfig CONFIG = GeneralConfig.getInstance();
private static boolean croppedImageExists(IRenderableCard face) {
return MagicFileSystem.getCroppedCardImage(face).exists();
}
private static boolean tryDownloadingFile(DownloadableFile aFile) {
try {
aFile.doDownload();
return true;
} catch (IOException ex) {
return false;
}
}
public static boolean tryDownloadingCroppedImage(CardImageFile imageFile) throws MalformedURLException, DownloadException {
MagicCardDefinition card = imageFile.getCard();
if (card.getImageURL().contains("magiccards.info/scans/")) {
URL remote = new URL(card.getImageURL().replace("/scans/", "/crop/"));
if (UrlHelper.isUrlValid(remote)) {
File local = MagicFileSystem.getCroppedCardImage(imageFile.getCard());
return tryDownloadingFile(new DownloadableFile(local, remote));
}
}
return false;
}
private static void tryDownloadingCroppedImage(IRenderableCard face) throws DownloadException {
try {
tryDownloadingCroppedImage(new CardImageFile(face));
} catch (MalformedURLException ex) {
throw new DownloadException(String.format("%s [%s]", ex.toString(), face.getImageName()), ex);
}
}
static BufferedImage get(IRenderableCard face) throws DownloadException {
if (CONFIG.getImagesOnDemand()) {
if (!croppedImageExists(face) && !PrintedCardImage.imageExists(face)) {
tryDownloadingCroppedImage(face);
}
if (!croppedImageExists(face) && !PrintedCardImage.imageExists(face)) {
// CB can extract crop from printed image as a last resort.
PrintedCardImage.get(face);
}
}
return CardBuilder.getCardBuilderImage(face);
}
}

View File

@ -7,6 +7,7 @@ import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import magic.data.DownloadableFile;
import magic.ui.CardTextLanguage;
public final class UrlHelper {
@ -43,10 +44,10 @@ public final class UrlHelper {
/**
* Returns a {@code magiccards.info} image url for a given non-English language code.
*/
public static URL getAlternateMagicCardsImageUrl(URL defaultUrl, CardTextLanguage lang) throws MalformedURLException {
public static URL getAltMagicCardsInfoUrl(DownloadableFile aFile, CardTextLanguage lang) throws MalformedURLException {
final String BASE = "/magiccards.info/scans/";
final String TARGET = BASE + "en/";
final String s = defaultUrl.toExternalForm();
final String s = aFile.getUrl().toExternalForm();
return s.contains(TARGET)
? new URL(s.replaceAll(TARGET, BASE + lang.getMagicCardsCode() + "/"))
: null;
@ -71,6 +72,6 @@ public final class UrlHelper {
return false;
}
}
private UrlHelper() { }
}

View File

@ -13,10 +13,9 @@ import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import magic.data.MagicIcon;
import magic.translate.MText;
import magic.ui.CardTextLanguage;
import magic.ui.MagicImages;
import magic.ui.helpers.UrlHelper;
import magic.ui.dialog.button.CloseButton;
import magic.ui.helpers.UrlHelper;
import net.miginfocom.swing.MigLayout;
@SuppressWarnings("serial")
@ -31,8 +30,7 @@ class DialogMainPanel extends JPanel implements PropertyChangeListener {
private static final String _S3 = "Run in background...";
private static final String _S4 = "Opens a page containing more information on this screen in your internet browser.";
private static final String _S6 = "Downloads card images that are missing or out-of-date in the 'cards' and 'tokens' folders.";
private static final String _S7 = "Downloads cropped images that are missing or out-of-date in the 'crops' folder. <b>Not 100% coverage</b>, currently there is not a downloadable cropped image for every card.";
private static final String _S8 = "Magarena will display the first image it finds using the folder order:- 'custom', 'crops', 'cards' or 'tokens'. If a cropped image is found or the image is missing then a proxy card image will be generated.";
private static final String _S7 = "<b>Not 100% coverage</b>. Please note there may be a bit of a delay the first time a proxy image is requested while the rendering sub-system is loaded and intialized.";
private final JButton backgroundButton;
private final OptionsPanel optionsPanel;
@ -46,13 +44,6 @@ class DialogMainPanel extends JPanel implements PropertyChangeListener {
hintPanel = new HintPanel(getDefaultHint());
optionsPanel = new OptionsPanel();
optionsPanel.addHintSources(hintPanel);
optionsPanel.setEnabled(false);
optionsPanel.addPropertyChangeListener(OptionsPanel.CP_OPTIONS_CHANGED,
(e) -> { refreshDownloadList(); }
);
backgroundButton = new JButton(MText.get(_S3));
backgroundButton.setFocusable(false);
backgroundButton.addActionListener((a) -> { doRunInBackground(); });
@ -63,17 +54,20 @@ class DialogMainPanel extends JPanel implements PropertyChangeListener {
buttonsPanel = new ButtonsPanel();
optionsPanel = new OptionsPanel(this);
optionsPanel.addHintSources(hintPanel);
setDownloadPanels();
setLookAndFeel();
refreshLayout();
updateComponentState();
}
private String getDefaultHint() {
return String.format("<b>%s</b><br>%s<br><br><b>%s</b><br>%s<br><br>%s",
return String.format("<b>%s</b><br>%s<br><br><b>%s</b><br>%s",
CardImageDisplayMode.PRINTED.toString(), MText.get(_S6),
CardImageDisplayMode.PROXY.toString(), MText.get(_S7),
MText.get(_S8)
CardImageDisplayMode.PROXY.toString(), MText.get(_S7)
);
}
@ -82,18 +76,18 @@ class DialogMainPanel extends JPanel implements PropertyChangeListener {
}
private void refreshDownloadList() {
final CardImageDisplayMode mode = optionsPanel.getDisplayMode();
final CardTextLanguage lang = optionsPanel.getCardTextLanguage();
CardImageDisplayMode mode = optionsPanel.getCardImageDisplayMode();
for (DownloadPanel panel : downloadPanels) {
panel.refreshDownloadList(mode, lang);
panel.doCancel();
panel.refreshDownloadList(mode);
}
}
private void setDownloadPanels() {
downloadPanels.add(getPlayableDownloaderPanel());
downloadPanels.add(getUnimplementedDownloaderPanel());
downloadPanel.setLayout(new MigLayout("flowy, insets 6 0 6 0, gapy 0"));
downloadPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, Color.GRAY));
downloadPanel.setLayout(new MigLayout("flowy, insets 0 0 6 0, gapy 0"));
downloadPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.GRAY));
for (DownloadPanel panel : downloadPanels) {
downloadPanel.add(panel, "w 100%");
}
@ -116,8 +110,7 @@ class DialogMainPanel extends JPanel implements PropertyChangeListener {
private DownloadPanel getPlayableDownloaderPanel() {
final DownloadPanel playableDownloaderPanel = new PlayablePanel(
optionsPanel.getDisplayMode(),
optionsPanel.getCardTextLanguage(),
optionsPanel.getCardImageDisplayMode(),
this
);
playableDownloaderPanel.addPropertyChangeListener(DownloadPanel.CP_STATE_CHANGED, this);
@ -126,8 +119,7 @@ class DialogMainPanel extends JPanel implements PropertyChangeListener {
private DownloadPanel getUnimplementedDownloaderPanel() {
final DownloadPanel unimplementedDownloaderPanel = new UnimplementedPanel(
optionsPanel.getDisplayMode(),
optionsPanel.getCardTextLanguage(),
optionsPanel.getCardImageDisplayMode(),
this
);
unimplementedDownloaderPanel.addPropertyChangeListener(DownloadPanel.CP_STATE_CHANGED, this);
@ -146,12 +138,17 @@ class DialogMainPanel extends JPanel implements PropertyChangeListener {
activePanel = panel;
}
}
if (optionsPanel != null) {
optionsPanel.setEnabled(!isDownloading);
}
for (DownloadPanel panel : downloadPanels) {
panel.setEnabled(!optionsPanel.isOnDemand());
}
if (activePanel != null) {
for (DownloadPanel panel : downloadPanels) {
panel.setLocked(panel != activePanel);
}
}
optionsPanel.setEnabled(!isScanning && !isDownloading);
buttonsPanel.setIsDownloading(isDownloading);
}
@ -165,6 +162,20 @@ class DialogMainPanel extends JPanel implements PropertyChangeListener {
return false;
}
void doOnImageFolderChanged() {
refreshDownloadList();
updateComponentState();
}
void doOnDisplayModeChanged() {
refreshDownloadList();
updateComponentState();
}
void doOnDemandChanged() {
updateComponentState();
}
private class ButtonsPanel extends JPanel {
private final JButton closeButton;
@ -204,6 +215,7 @@ class DialogMainPanel extends JPanel implements PropertyChangeListener {
for (DownloadPanel panel : downloadPanels) {
panel.doCancel();
}
optionsPanel.saveSettings();
firePropertyChange(CP_CLOSE, true, false);
}

View File

@ -3,6 +3,7 @@ package magic.ui.screen.images.download;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.MouseListener;
import java.io.File;
@ -14,8 +15,8 @@ import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JTextField;
import magic.translate.MText;
import magic.ui.ScreenController;
import magic.ui.FontsAndBorders;
import magic.ui.ScreenController;
import magic.ui.widget.M.MFileLink;
import magic.utility.MagicFileSystem;
import magic.utility.MagicFileSystem.DataPath;
@ -82,7 +83,7 @@ public class DirectoryChooser extends JPanel {
imagesFolder.setFile(defaultPath);
imagesFolder.setToolTipText(MText.get(_S6));
imagesFolder.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createMatteBorder(1, 1, 1, 1, Color.GRAY),
BorderFactory.createMatteBorder(1, 1, 1, 1, Color.GRAY),
BorderFactory.createEmptyBorder(0, 4, 0, 0))
);
}
@ -99,6 +100,10 @@ public class DirectoryChooser extends JPanel {
));
}
void setBold(boolean b) {
imagesFolder.setFont(imagesFolder.getFont().deriveFont(b ? Font.BOLD : Font.PLAIN));
}
private static class ImagesDirectoryChooser extends JFileChooser {
public ImagesDirectoryChooser(String currentDirectoryPath) {
super(currentDirectoryPath);

View File

@ -2,9 +2,10 @@ package magic.ui.screen.images.download;
import java.awt.Font;
import java.io.IOException;
import java.net.Proxy;
import java.util.Collection;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
import javax.swing.ImageIcon;
import javax.swing.JButton;
@ -21,9 +22,8 @@ import magic.data.ImagesDownloadList;
import magic.data.MagicIcon;
import magic.model.MagicCardDefinition;
import magic.translate.MText;
import magic.ui.CardTextLanguage;
import magic.ui.MagicCardImages;
import magic.ui.MagicImages;
import magic.utility.MagicFileSystem;
import net.miginfocom.swing.MigLayout;
@SuppressWarnings("serial")
@ -34,7 +34,9 @@ abstract class DownloadPanel extends JPanel implements IScanListener, IDownloadL
// translatable strings
private static final String _S1 = "Cancel";
protected final GeneralConfig CONFIG = GeneralConfig.getInstance();
private static final Logger LOGGER = Logger.getLogger(DownloadPanel.class.getName());
protected static final GeneralConfig CONFIG = GeneralConfig.getInstance();
private final MigLayout migLayout = new MigLayout();
protected final JLabel captionLabel = getCaptionLabel(getProgressCaption());
@ -43,20 +45,17 @@ abstract class DownloadPanel extends JPanel implements IScanListener, IDownloadL
protected final JProgressBar progressBar = new JProgressBar();
private ImagesDownloadList files;
private boolean isCancelled = false;
private SwingWorker<Void, Integer> imagesDownloader;
private ScanWorker imagesScanner;
private DownloadState downloaderState = DownloadState.STOPPED;
private CardImageDisplayMode displayMode = CardImageDisplayMode.PRINTED;
private CardTextLanguage textLanguage = CardTextLanguage.ENGLISH;
private final DialogMainPanel mainPanel;
protected abstract String getProgressCaption();
protected abstract String getDownloadButtonCaption();
DownloadPanel(CardImageDisplayMode aMode, CardTextLanguage aLang, DialogMainPanel aPanel) {
DownloadPanel(CardImageDisplayMode aMode, DialogMainPanel aPanel) {
this.displayMode = aMode;
this.textLanguage = aLang;
this.mainPanel = aPanel;
setLookAndFeel();
refreshLayout();
@ -70,7 +69,7 @@ abstract class DownloadPanel extends JPanel implements IScanListener, IDownloadL
private void doRunImageDownloadWorker() {
setDownloadingState();
imagesDownloader = new DownloadWorker(this, textLanguage, displayMode);
imagesDownloader = new DownloadWorker(this, displayMode);
imagesDownloader.execute();
notifyStatusChanged(DownloadState.DOWNLOADING);
}
@ -85,7 +84,6 @@ abstract class DownloadPanel extends JPanel implements IScanListener, IDownloadL
}
void doCancel() {
isCancelled = true;
doCancelImageDownloadWorker();
doCancelImagesScanner();
}
@ -108,14 +106,16 @@ abstract class DownloadPanel extends JPanel implements IScanListener, IDownloadL
if (imagesScanner != null && !imagesScanner.isDone()) {
imagesScanner.cancel(true);
}
if (!isCancelled) {
captionLabel.setIcon(MagicImages.getIcon(MagicIcon.BUSY16));
captionLabel.setText(getProgressCaption());
imagesScanner = new ScanWorker(this, displayMode);
imagesScanner.execute();
downloadButton.setEnabled(false);
notifyStatusChanged(DownloadState.SCANNING);
if (imagesScanner != null && !imagesScanner.isDone()) {
LOGGER.log(Level.WARNING, "Scanner still running!");
return;
}
captionLabel.setIcon(MagicImages.getIcon(MagicIcon.BUSY16));
captionLabel.setText(getProgressCaption());
imagesScanner = new ScanWorker(this, displayMode);
imagesScanner.execute();
downloadButton.setEnabled(false);
notifyStatusChanged(DownloadState.SCANNING);
}
private void resetProgressBar() {
@ -186,9 +186,9 @@ abstract class DownloadPanel extends JPanel implements IScanListener, IDownloadL
);
}
void refreshDownloadList(CardImageDisplayMode aMode, CardTextLanguage aLang) {
void refreshDownloadList(CardImageDisplayMode aMode) {
doCancel();
this.displayMode = aMode;
this.textLanguage = aLang;
buildDownloadImagesList();
}
@ -212,8 +212,8 @@ abstract class DownloadPanel extends JPanel implements IScanListener, IDownloadL
progressBar.setString(null);
}
protected String doFileDownloadAndGetName(final DownloadableFile file, final Proxy proxy) throws IOException {
file.doDownload(proxy);
protected String doFileDownloadAndGetName(final DownloadableFile file) throws IOException {
file.doDownload();
if (file instanceof CardImageFile) {
return ((CardImageFile) file).getCardName();
} else {
@ -225,23 +225,38 @@ abstract class DownloadPanel extends JPanel implements IScanListener, IDownloadL
return countInteger;
}
private static boolean isImageFileMissing(MagicCardDefinition card, CardImageDisplayMode mode) {
if (mode == CardImageDisplayMode.PRINTED) {
return !MagicFileSystem.getPrintedCardImage(card).exists();
} else {
return !MagicFileSystem.getCroppedCardImage(card).exists()
&& !MagicFileSystem.getPrintedCardImage(card).exists();
private static boolean requiresNewImageDownload(MagicCardDefinition card, Date lastDownloadDate) {
if (!card.hasImageUrl()) {
return false;
}
if (MagicCardImages.isCustomCardImageFound(card)) {
return false;
}
if (card.isImageUpdatedAfter(lastDownloadDate)) {
return true;
}
if (CONFIG.getCardImageDisplayMode() == CardImageDisplayMode.PRINTED) {
return MagicCardImages.isPrintedCardImageMissing(card);
} else { // PROXY
return MagicCardImages.isCroppedCardImageMissing(card)
&& MagicCardImages.isPrintedCardImageMissing(card);
}
}
protected static Stream<MagicCardDefinition> getCards(Collection<MagicCardDefinition> cards, Date aDate, CardImageDisplayMode mode) {
return cards.stream()
.filter(MagicCardDefinition::hasImageUrl)
.filter(card -> card.isImageUpdatedAfter(aDate) || isImageFileMissing(card, mode));
return cards.stream().filter(card -> requiresNewImageDownload(card, aDate));
}
void setLocked(boolean b) {
downloadButton.setEnabled(!b && files != null && !files.isEmpty());
}
@Override
public void setEnabled(boolean b) {
super.setEnabled(b);
downloadButton.setEnabled(b);
progressBar.setEnabled(b);
captionLabel.setEnabled(b);
}
}

View File

@ -3,7 +3,6 @@ package magic.ui.screen.images.download;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URL;
import java.nio.file.Files;
import java.time.LocalDateTime;
@ -14,40 +13,35 @@ import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import magic.data.CardImageFile;
import magic.data.DownloadableFile;
import magic.data.GeneralConfig;
import magic.data.ImagesDownloadList;
import magic.model.MagicCardDefinition;
import magic.exception.DownloadException;
import magic.ui.CardTextLanguage;
import magic.ui.MagicImages;
import magic.ui.MagicLogFile;
import magic.ui.helpers.UrlHelper;
import magic.utility.MagicFileSystem;
import magic.ui.PrintedCardImage;
import magic.ui.ProxyCardImage;
import magic.utility.MagicSystem;
class DownloadWorker extends SwingWorker<Void, Integer> {
private static final MagicLogFile missingLog = new MagicLogFile("downloaded-images");
private final Proxy proxy;
private ImagesDownloadList downloadList;
private final IDownloadListener listener;
private final CardTextLanguage textLanguage;
private final CardImageDisplayMode displayMode;
private boolean updateDownloadDate = true;
private boolean isLogging = true;
private int serverBusyCooldown = 1; // in millisecs
DownloadWorker(IDownloadListener aListener, CardTextLanguage aLanguage, CardImageDisplayMode aMode) {
DownloadWorker(IDownloadListener aListener, CardImageDisplayMode aMode) {
this.listener = aListener;
this.textLanguage = aLanguage;
this.displayMode = aMode;
this.proxy = GeneralConfig.getInstance().getProxy();
}
@Override
protected Void doInBackground() throws MalformedURLException {
this.downloadList = ScanWorker.getImagesDownloadList((IScanListener)listener, displayMode);
doDownloadImages(textLanguage);
doDownloadImages();
return null;
}
@ -113,51 +107,12 @@ class DownloadWorker extends SwingWorker<Void, Integer> {
}
}
/**
* Gets alternate magiccards.info image url for given card text language.
* If it fails then displays reason in error log panel and returns null url.
*/
private URL getAlternateUrl(DownloadableFile aFile, CardTextLanguage textLang) {
try {
return UrlHelper.getAlternateMagicCardsImageUrl(aFile.getUrl(), textLang);
} catch (MalformedURLException ex) {
listener.setMessage(String.format("%s [%s]", ex.toString(), aFile.getUrl()));
return null;
}
}
private void setServerBusyCooldown(String errmsg) {
if (errmsg.contains("HTTP response code: 503")) {
serverBusyCooldown += 100;
}
}
/**
* Attempts to download alternate card image.
* If it fails displays reason in error log panel.
*/
private boolean tryAlternateDownload(final DownloadableFile aFile, CardTextLanguage aLang) {
try {
aFile.doDownload(proxy);
} catch (IOException ex) {
listener.setMessage(String.format("%s [%s (%s)]", ex.toString(), aFile.getFilename(), aLang));
setServerBusyCooldown(ex.toString());
return false;
}
return true;
}
private boolean downloadAlternateCardImage(final CardImageFile aFile, CardTextLanguage aLang) {
final URL altUrl = getAlternateUrl(aFile, aLang);
if (UrlHelper.isUrlValid(altUrl)) {
if (tryAlternateDownload(new DownloadableFile(aFile.getLocalFile(), altUrl), aLang)) {
doLog(aFile.getCardName(), aLang, altUrl);
return true;
}
}
return false;
}
private boolean doDeleteLocalImageFile(File aFile) {
try {
Files.deleteIfExists(aFile.toPath());
@ -168,50 +123,30 @@ class DownloadWorker extends SwingWorker<Void, Integer> {
return true;
}
/**
* Attempts to download default card image.
* If it fails displays reason in error log panel.
*/
private boolean tryDefaultDownload(final DownloadableFile aFile) {
private void downloadPrintedImage(CardImageFile imageFile) {
try {
aFile.doDownload(proxy);
} catch (IOException ex) {
// if local file exists then download was triggered by the
// 'image_updated' script property. But download failed so
// remove local image so it becomes 'missing' instead.
updateDownloadDate = displayMode != CardImageDisplayMode.PROXY && doDeleteLocalImageFile(aFile.getLocalFile());
listener.setMessage(String.format("%s [%s]", ex.toString(), aFile.getFilename()));
PrintedCardImage.tryDownloadingPrintedImage(imageFile);
} catch (DownloadException ex) {
listener.setMessage(ex.getMessage());
setServerBusyCooldown(ex.toString());
return false;
}
return true;
}
private void downloadDefaultCardImage(final CardImageFile aFile) {
if (tryDefaultDownload(aFile)) {
doLog(aFile.getCardName(), CardTextLanguage.ENGLISH, null);
}
}
private boolean doDownloadCroppedImage(CardImageFile imageFile) throws MalformedURLException {
final MagicCardDefinition card = imageFile.getCard();
final File local = MagicFileSystem.getCroppedCardImage(imageFile.getCard());
if (card.getImageURL().contains("magiccards.info/scans/")) {
final URL remote = new URL(card.getImageURL().replace("/scans/", "/crop/"));
if (UrlHelper.isUrlValid(remote)) {
if (tryDefaultDownload(new DownloadableFile(local, remote))) {
doLog(card.getCardTextName(), CardTextLanguage.ENGLISH, remote);
return true;
}
if (ex.getCause() instanceof IOException) {
// if local image file already existed before download then
// download was triggered by the 'image_updated' script property.
// As download failed remove local image so it gets picked up
// by the missing image trigger instead. If unable to remove
// local image then don't update 'imageDownloaderRunDate'.
updateDownloadDate = doDeleteLocalImageFile(imageFile.getLocalFile());
}
}
return false;
}
private void doDownloadPrintedImage(CardImageFile imageFile, CardTextLanguage textLang) throws MalformedURLException {
if (textLang.isEnglish() || !downloadAlternateCardImage(imageFile, textLang)) {
downloadDefaultCardImage(imageFile);
private boolean tryDownloadingCroppedImage(CardImageFile imageFile) {
try {
return ProxyCardImage.tryDownloadingCroppedImage(imageFile);
} catch (DownloadException | MalformedURLException ex) {
System.err.println(String.format("%s [%s]", ex.toString(), imageFile.getFilename()));
}
return false;
}
private void doPause(int millisecs) {
@ -222,24 +157,23 @@ class DownloadWorker extends SwingWorker<Void, Integer> {
}
}
private void doDownloadImages(CardTextLanguage textLang) throws MalformedURLException {
private void doDownloadImages() throws MalformedURLException {
assert !SwingUtilities.isEventDispatchThread();
initializeLogFiles();
int fileCount = 0;
updateDownloadDate = displayMode != CardImageDisplayMode.PROXY;
for (DownloadableFile dFile : downloadList) {
final CardImageFile imageFile = (CardImageFile) dFile;
if (displayMode == CardImageDisplayMode.PROXY) {
if (!doDownloadCroppedImage(imageFile)) {
doDownloadPrintedImage(imageFile, textLang);
if (!tryDownloadingCroppedImage(imageFile)) {
downloadPrintedImage(imageFile);
}
} else {
doDownloadPrintedImage(imageFile, textLang);
downloadPrintedImage(imageFile);
}
doPause(serverBusyCooldown);

View File

@ -1,51 +1,69 @@
package magic.ui.screen.images.download;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ItemEvent;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import magic.data.GeneralConfig;
import magic.translate.MText;
import magic.ui.CardTextLanguage;
import magic.ui.dialog.prefs.ImageSizePresets;
import net.miginfocom.swing.MigLayout;
@SuppressWarnings("serial")
class OptionsPanel extends JPanel {
private static final String _S1 = "Images folder:";
private static final String _S2 = "Card text:";
private static final String _S3 = "Display:";
private static final String _S2 = "Preferred card text:";
private static final String _S3 = "Display card image as:";
private static final String _S4 = "Preferred card text language";
private static final String _S5 = "If a language other than English is selected then Magarena will try to find and download a card image for the given language. If no image is found then it will download the default English edition instead.";
static final String CP_OPTIONS_CHANGED = "fc9a1955-7e59-47d5-83b4-14db558c731e";
private static final String _S5 = "If a language other than English is selected then Magarena will first try to download a card image with text in that language. If no image is found then it will download the default English card image instead.";
private static final String _S11 = "Not applicable to rendered proxy images.";
private static final String _S6 = "Download on demand:";
private static final String _S7 = "Only downloads card images as needed. Switch off if you want to download all images in one go, use proxy frames with cropped images or download non-English card images.";
private static final String _S8 = "Preferred display size:";
private static final String _S9 = "Sets the size of the card image displayed in card explorer and deck editor as well as popup images during a game. Select 'Default' to display the card image at its native size. Otherwise it will be scaled up or down to the selected preset.";
private static final String _S10 = "** This has no affect on the size of an image that is downloaded **";
private final GeneralConfig CONFIG = GeneralConfig.getInstance();
private final JComboBox<CardTextLanguage> cboCardText = new JComboBox<>();
private final JComboBox<CardImageDisplayMode> cboDisplayMode = new JComboBox<>();
private final DirectoryChooser imagesFolderChooser;
private final JComboBox<Boolean> cboOnDemand = new JComboBox<>();
private final JComboBox<ImageSizePresets> cboDisplaySize = new JComboBox<>();
private final DialogMainPanel listener;
OptionsPanel() {
OptionsPanel(DialogMainPanel listener) {
this.listener = listener;
imagesFolderChooser = getImagesFolderChooser();
setCardTextCombo();
imagesFolderChooser.setBold(true);
setDisplayModeCombo();
setDisplaySizeCombo();
setCardTextCombo();
setOnDemandCombo();
setLayout(new MigLayout("wrap 2, insets 0", "[right][]"));
setLayout(new MigLayout("wrap 2, insets 0", "[right, 40%][60%]"));
// image folder
add(new JLabel(MText.get(_S1)));
add(imagesFolderChooser, "w 100%");
// card text language
add(new JLabel(MText.get(_S2)));
add(cboCardText);
// download mode
add(imagesFolderChooser, "w 100%, spanx 2");
add(getBoldLabel(MText.get(_S3)));
add(cboDisplayMode);
add(getBoldLabel(MText.get(_S2)));
add(cboCardText);
add(getBoldLabel(MText.get(_S8)));
add(cboDisplaySize);
add(getBoldLabel(MText.get(_S6)));
add(cboOnDemand);
setOptionsState();
}
private JLabel getBoldLabel(String text) {
@ -54,50 +72,77 @@ class OptionsPanel extends JPanel {
return lbl;
}
private void saveSettings() {
CONFIG.setCardTextLanguage(getCardTextLanguage());
CONFIG.setCardImagesPath(imagesFolderChooser.getPath());
CONFIG.save();
}
private void doImageFolderChanged() {
setEnabled(false);
saveSettings();
firePropertyChange(CP_OPTIONS_CHANGED, true, false);
void saveSettings() {
CONFIG.setCardImageDisplayMode(getCardImageDisplayMode());
CONFIG.setPreferredImageSize(getPreferredImageSize());
CONFIG.setImagesOnDemand(isOnDemand());
if (getCardImageDisplayMode() == CardImageDisplayMode.PRINTED) {
CONFIG.setCardTextLanguage(getCardTextLanguage());
}
}
private DirectoryChooser getImagesFolderChooser() {
final DirectoryChooser chooser = new DirectoryChooser(CONFIG.getCardImagesPath());
chooser.setFocusable(false);
chooser.addPropertyChangeListener(DirectoryChooser.CP_FOLDER_CHANGED, (e) -> {
doImageFolderChanged();
CONFIG.setCardImagesPath(chooser.getPath());
listener.doOnImageFolderChanged();
});
return chooser;
}
private void doTextLanguageChanged() {
saveSettings();
firePropertyChange(CP_OPTIONS_CHANGED, true, false);
}
private void setCardTextCombo() {
cboCardText.setModel(new DefaultComboBoxModel<>(CardTextLanguage.values()));
cboCardText.setSelectedItem(CONFIG.getCardTextLanguage());
cboCardText.addItemListener((ItemEvent ev) -> {
if (ev.getStateChange() == ItemEvent.SELECTED) {
doTextLanguageChanged();
cboCardText.addItemListener((final ItemEvent e) -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
if (getCardImageDisplayMode() == CardImageDisplayMode.PRINTED) {
CONFIG.setCardTextLanguage(getCardTextLanguage());
}
}
});
}
private void setOptionsState() {
if (getCardImageDisplayMode() == CardImageDisplayMode.PROXY) {
cboCardText.setSelectedItem(CardTextLanguage.ENGLISH);
cboCardText.setEnabled(false);
} else {
cboCardText.setSelectedItem(CONFIG.getCardTextLanguage());
cboCardText.setEnabled(true);
}
}
private void doDisplayModeChanged() {
setEnabled(false);
firePropertyChange(CP_OPTIONS_CHANGED, true, false);
CONFIG.setCardImageDisplayMode((CardImageDisplayMode) cboDisplayMode.getSelectedItem());
setOptionsState();
listener.doOnDisplayModeChanged();
}
private void doOnDemandChanged() {
CONFIG.setImagesOnDemand(isOnDemand());
listener.doOnDemandChanged();
}
private void setOnDemandCombo() {
cboOnDemand.setModel(new DefaultComboBoxModel<>(new Boolean[]{true, false}));
cboOnDemand.getModel().setSelectedItem(CONFIG.getImagesOnDemand());
cboOnDemand.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
setText((Boolean) value == true ? "Yes" : "No");
setForeground(cboOnDemand.isEnabled() ? getForeground() : Color.GRAY);
return this;
}
});
cboOnDemand.addItemListener((final ItemEvent e) -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
doOnDemandChanged();
}
});
}
private void setDisplayModeCombo() {
cboDisplayMode.setFont(cboDisplayMode.getFont().deriveFont(Font.BOLD));
cboDisplayMode.setModel(new DefaultComboBoxModel<>(CardImageDisplayMode.values()));
cboDisplayMode.getModel().setSelectedItem(CONFIG.getCardImageDisplayMode());
cboDisplayMode.addItemListener((final ItemEvent e) -> {
@ -107,27 +152,48 @@ class OptionsPanel extends JPanel {
});
}
@Override
public void setEnabled(boolean b) {
super.setEnabled(b);
for (Component c : getComponents()) {
c.setEnabled(b);
}
private void setDisplaySizeCombo() {
cboDisplaySize.setModel(new DefaultComboBoxModel<>(ImageSizePresets.values()));
cboDisplaySize.getModel().setSelectedItem(CONFIG.getPreferredImageSize());
}
CardImageDisplayMode getDisplayMode() {
return (CardImageDisplayMode) cboDisplayMode.getSelectedItem();
void addHintSources(HintPanel hintPanel) {
imagesFolderChooser.addHintSources(hintPanel);
hintPanel.addHintSource(cboCardText, String.format("<b>%s</b><br>%s<br><br><b>%s</b>",
MText.get(_S4), MText.get(_S5), MText.get(_S11)
));
hintPanel.addHintSource(cboOnDemand, String.format("<b>%s</b><br>%s",
MText.get(_S6), MText.get(_S7)
));
hintPanel.addHintSource(cboDisplaySize, String.format("<b>%s</b><br>%s<br><br><b>%s</b>",
MText.get(_S8), MText.get(_S9), MText.get(_S10)
));
}
boolean isOnDemand() {
return (Boolean) cboOnDemand.getSelectedItem();
}
CardTextLanguage getCardTextLanguage() {
return (CardTextLanguage) cboCardText.getSelectedItem();
}
void addHintSources(HintPanel hintPanel) {
imagesFolderChooser.addHintSources(hintPanel);
hintPanel.addHintSource(cboCardText, String.format("<b>%s</b><br>%s",
MText.get(_S4), MText.get(_S5)
));
CardImageDisplayMode getCardImageDisplayMode() {
return (CardImageDisplayMode) cboDisplayMode.getSelectedItem();
}
private ImageSizePresets getPreferredImageSize() {
return (ImageSizePresets) cboDisplaySize.getSelectedItem();
}
@Override
public void setEnabled(boolean b) {
super.setEnabled(b);
imagesFolderChooser.setEnabled(b);
cboDisplayMode.setEnabled(b);
cboCardText.setEnabled(b && getCardImageDisplayMode() == CardImageDisplayMode.PRINTED);
cboDisplaySize.setEnabled(b);
cboOnDemand.setEnabled(b);
}
}

View File

@ -6,17 +6,16 @@ import magic.data.CardDefinitions;
import magic.data.GeneralConfig;
import magic.model.MagicCardDefinition;
import magic.translate.MText;
import magic.ui.CardTextLanguage;
@SuppressWarnings("serial")
class PlayablePanel extends DownloadPanel {
// translatable strings
private static final String _S1 = "Playable";
private static final String _S1 = "Missing images for playable cards";
private static final String _S2 = "Download";
PlayablePanel(CardImageDisplayMode aMode, CardTextLanguage aLang, DialogMainPanel aPanel) {
super(aMode, aLang, aPanel);
PlayablePanel(CardImageDisplayMode aMode, DialogMainPanel aPanel) {
super(aMode, aPanel);
}
@Override

View File

@ -6,17 +6,16 @@ import magic.data.CardDefinitions;
import magic.data.GeneralConfig;
import magic.model.MagicCardDefinition;
import magic.translate.MText;
import magic.ui.CardTextLanguage;
@SuppressWarnings("serial")
class UnimplementedPanel extends DownloadPanel {
// translatable strings
private static final String _S1 = "Unimplemented";
private static final String _S1 = "Missing images for unimplemented cards";
private static final String _S2 = "Download";
UnimplementedPanel(CardImageDisplayMode aMode, CardTextLanguage aLang, DialogMainPanel aPanel) {
super(aMode, aLang, aPanel);
UnimplementedPanel(CardImageDisplayMode aMode, DialogMainPanel aPanel) {
super(aMode, aPanel);
}
@Override

View File

@ -148,6 +148,10 @@ public class MFileLink extends MWidget {
label.setFont(aFont);
}
public Font getFont() {
return label.getFont();
}
public void setVisible(boolean b) {
label.setVisible(b);
}