All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tinymediamanager.ui.dialogs.ImageChooserDialog Maven / Gradle / Ivy

/*
 * Copyright 2012 - 2019 Manuel Laggner
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.tinymediamanager.ui.dialogs;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.InterruptedIOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

import org.apache.commons.lang3.StringUtils;
import org.imgscalr.Scalr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tinymediamanager.core.ImageUtils;
import org.tinymediamanager.core.TmmProperties;
import org.tinymediamanager.core.Utils;
import org.tinymediamanager.core.movie.MovieModuleManager;
import org.tinymediamanager.core.tvshow.TvShowModuleManager;
import org.tinymediamanager.scraper.MediaScrapeOptions;
import org.tinymediamanager.scraper.MediaScraper;
import org.tinymediamanager.scraper.entities.MediaArtwork;
import org.tinymediamanager.scraper.entities.MediaArtwork.ImageSizeAndUrl;
import org.tinymediamanager.scraper.entities.MediaArtwork.MediaArtworkType;
import org.tinymediamanager.scraper.entities.MediaType;
import org.tinymediamanager.scraper.exceptions.MissingIdException;
import org.tinymediamanager.scraper.exceptions.ScrapeException;
import org.tinymediamanager.scraper.http.Url;
import org.tinymediamanager.scraper.mediaprovider.IMediaArtworkProvider;
import org.tinymediamanager.ui.IconManager;
import org.tinymediamanager.ui.MainWindow;
import org.tinymediamanager.ui.TmmFontHelper;
import org.tinymediamanager.ui.TmmUIHelper;
import org.tinymediamanager.ui.ToggleButtonUI;
import org.tinymediamanager.ui.UIConstants;
import org.tinymediamanager.ui.WrapLayout;
import org.tinymediamanager.ui.components.EnhancedTextField;
import org.tinymediamanager.ui.components.ImageLabel;
import org.tinymediamanager.ui.components.LinkLabel;

import net.miginfocom.swing.MigLayout;

/**
 * The Class ImageChooser. Let the user choose the right image for the media entity
 * 
 * @author Manuel Laggner
 */
public class ImageChooserDialog extends TmmDialog {
  private static final long   serialVersionUID = 8193355920006275933L;
  private static final Logger LOGGER           = LoggerFactory.getLogger(ImageChooserDialog.class);
  private static final String DIALOG_ID        = "imageChooser";
  private static final Insets BUTTON_MARGIN    = UIConstants.SMALL_BUTTON_MARGIN;

  public enum ImageType {
    POSTER,
    FANART,
    BANNER,
    SEASON_POSTER,
    SEASON_BANNER,
    SEASON_THUMB,
    LOGO,
    CLEARLOGO,
    CLEARART,
    CHARACTERART,
    DISC,
    THUMB,
    KEYART
  }

  private Map ids;
  private ImageType           type;
  private MediaType           mediaType;
  private ImageLabel          imageLabel;
  private List        extraThumbs;
  private List        extraFanarts;
  private List  artworkScrapers;

  private JProgressBar        progressBar;
  private JLabel              lblProgressAction;
  private JPanel              panelImages;
  private JScrollPane         scrollPane;
  private ButtonGroup         buttonGroup    = new ButtonGroup();
  private List buttons        = new ArrayList<>();
  private JTextField          tfImageUrl;
  private ToggleButtonUI      toggleButtonUI = new ToggleButtonUI();

  private DownloadTask        task;

  /**
   * Instantiates a new image chooser dialog.
   *
   * @param ids
   *          the ids
   * @param type
   *          the type
   * @param artworkScrapers
   *          the artwork providers
   * @param imageLabel
   *          the image label
   * @param mediaType
   *          the media for for which artwork has to be chosen
   */
  public ImageChooserDialog(final Map ids, ImageType type, List artworkScrapers, ImageLabel imageLabel,
      MediaType mediaType) {
    this(ids, type, artworkScrapers, imageLabel, new ArrayList<>(), new ArrayList<>(), mediaType);
  }

  /**
   * Instantiates a new image chooser dialog with extrathumbs and extrafanart usage.
   * 
   * @param ids
   *          the ids
   * @param type
   *          the type
   * @param artworkScrapers
   *          the artwork providers
   * @param imageLabel
   *          the image label
   * @param extraThumbs
   *          the extra thumbs
   * @param extraFanarts
   *          the extra fanarts
   * @param mediaType
   *          the media for for which artwork has to be chosen
   */
  public ImageChooserDialog(final Map ids, ImageType type, List artworkScrapers, ImageLabel imageLabel,
      List extraThumbs, List extraFanarts, MediaType mediaType) {
    super("", DIALOG_ID);
    this.imageLabel = imageLabel;
    this.type = type;
    this.mediaType = mediaType;
    this.extraThumbs = extraThumbs;
    this.extraFanarts = extraFanarts;
    this.ids = ids;
    this.artworkScrapers = artworkScrapers;
    init();
  }

  /**
   * Instantiates a new image chooser dialog.
   *
   * @param parent
   *          the parent of this dialog
   * @param ids
   *          the ids
   * @param type
   *          the type
   * @param artworkScrapers
   *          the artwork providers
   * @param imageLabel
   *          the image label
   * @param mediaType
   *          the media for for which artwork has to be chosen
   */
  public ImageChooserDialog(JDialog parent, final Map ids, ImageType type, List artworkScrapers, ImageLabel imageLabel,
      MediaType mediaType) {
    this(parent, ids, type, artworkScrapers, imageLabel, new ArrayList<>(), new ArrayList<>(), mediaType);
  }

  /**
   * Instantiates a new image chooser dialog with extrathumbs and extrafanart usage.
   *
   * @param parent
   *          the parent of this dialog
   * @param ids
   *          the ids
   * @param type
   *          the type
   * @param artworkScrapers
   *          the artwork providers
   * @param imageLabel
   *          the image label
   * @param extraThumbs
   *          the extra thumbs
   * @param extraFanarts
   *          the extra fanarts
   * @param mediaType
   *          the media for for which artwork has to be chosen
   */
  public ImageChooserDialog(JDialog parent, final Map ids, ImageType type, List artworkScrapers, ImageLabel imageLabel,
      List extraThumbs, List extraFanarts, MediaType mediaType) {
    super(parent, "", DIALOG_ID);
    this.imageLabel = imageLabel;
    this.type = type;
    this.mediaType = mediaType;
    this.extraThumbs = extraThumbs;
    this.extraFanarts = extraFanarts;
    this.ids = ids;
    this.artworkScrapers = artworkScrapers;
    init();
  }

  private void init() {
    switch (type) {
      case FANART:
        setTitle(BUNDLE.getString("image.choose.fanart")); //$NON-NLS-1$
        break;

      case POSTER:
        setTitle(BUNDLE.getString("image.choose.poster")); //$NON-NLS-1$
        break;

      case BANNER:
        setTitle(BUNDLE.getString("image.choose.banner")); //$NON-NLS-1$
        break;

      case SEASON_POSTER:
      case SEASON_BANNER:
      case SEASON_THUMB:
        Object season = ids.get("tvShowSeason");
        if (season != null) {
          setTitle(BUNDLE.getString("image.choose.season") + " - " + BUNDLE.getString("metatag.season") + " " + season); //$NON-NLS-1$
        }
        else {
          setTitle(BUNDLE.getString("image.choose.season")); //$NON-NLS-1$
        }
        break;

      case CLEARART:
        setTitle(BUNDLE.getString("image.choose.clearart")); //$NON-NLS-1$
        break;

      case DISC:
        setTitle(BUNDLE.getString("image.choose.disc")); //$NON-NLS-1$
        break;

      case LOGO:
        setTitle(BUNDLE.getString("image.choose.logo")); //$NON-NLS-1$
        break;

      case CLEARLOGO:
        setTitle(BUNDLE.getString("image.choose.clearlogo")); //$NON-NLS-1$
        break;

      case CHARACTERART:
        setTitle(BUNDLE.getString("image.choose.characterart")); //$NON-NLS-1$
        break;

      case THUMB:
        setTitle(BUNDLE.getString("image.choose.thumb")); //$NON-NLS-1$
        break;

      case KEYART:
        setTitle(BUNDLE.getString("image.choose.keyart")); //$NON-NLS-1$
        break;
    }

    /* UI components */
    JPanel contentPanel = new JPanel();
    getContentPane().add(contentPanel, BorderLayout.CENTER);
    contentPanel.setLayout(new MigLayout("hidemode 1", "[850lp,grow][]", "[500lp,grow][shrink 0][][][]"));
    {
      scrollPane = new JScrollPane();
      scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
      contentPanel.add(scrollPane, "cell 0 0 2 1,grow");
      {
        panelImages = new JPanel();
        scrollPane.setViewportView(panelImages);
        scrollPane.getVerticalScrollBar().setUnitIncrement(16);
        panelImages.setLayout(new WrapLayout(FlowLayout.LEFT));
      }
    }
    {
      JSeparator separator = new JSeparator();
      contentPanel.add(separator, "cell 0 1 2 1,growx");
    }
    {
      tfImageUrl = new EnhancedTextField(BUNDLE.getString("image.inserturl")); //$NON-NLS-1$
      contentPanel.add(tfImageUrl, "cell 0 2,growx");
      tfImageUrl.setColumns(10);
      JButton btnAddImage = new JButton(BUNDLE.getString("image.downloadimage")); //$NON-NLS-1$
      btnAddImage.addActionListener(e -> {
        if (StringUtils.isNotBlank(tfImageUrl.getText())) {
          downloadAndPreviewImage(tfImageUrl.getText());
        }
      });
      contentPanel.add(btnAddImage, "cell 1 2");

    }

    // add buttons to select/deselect all extrafanarts/extrathumbs
    if (type == ImageType.FANART && extraThumbs != null) {
      JLabel labelThumbs = new JLabel("Extrathumbs:");
      contentPanel.add(labelThumbs, "flowx,cell 0 2");

      JButton btnMarkExtrathumbs = new JButton("");
      contentPanel.add(btnMarkExtrathumbs, "cell 0 2");
      btnMarkExtrathumbs.setMargin(BUTTON_MARGIN);
      btnMarkExtrathumbs.setIcon(IconManager.CHECK_ALL);
      btnMarkExtrathumbs.setToolTipText(BUNDLE.getString("image.extrathumbs.markall")); //$NON-NLS-1$
      btnMarkExtrathumbs.addActionListener(arg0 -> {
        for (JToggleButton button : buttons) {
          if (button.getClientProperty("MediaArtworkExtrathumb") instanceof JCheckBox) {
            JCheckBox chkbx = (JCheckBox) button.getClientProperty("MediaArtworkExtrathumb");
            chkbx.setSelected(true);
          }
        }
      });

      JButton btnUnMarkExtrathumbs = new JButton("");
      contentPanel.add(btnUnMarkExtrathumbs, "cell 0 2");
      btnUnMarkExtrathumbs.setMargin(BUTTON_MARGIN);
      btnUnMarkExtrathumbs.setIcon(IconManager.CLEAR_ALL);
      btnUnMarkExtrathumbs.setToolTipText(BUNDLE.getString("image.extrathumbs.unmarkall")); //$NON-NLS-1$
      btnUnMarkExtrathumbs.addActionListener(arg0 -> {
        for (JToggleButton button : buttons) {
          if (button.getClientProperty("MediaArtworkExtrathumb") instanceof JCheckBox) {
            JCheckBox chkbx = (JCheckBox) button.getClientProperty("MediaArtworkExtrathumb");
            chkbx.setSelected(false);
          }
        }
      });
    }
    if (type == ImageType.FANART && extraFanarts != null) {
      JLabel labelFanart = new JLabel("Extrafanart:");
      contentPanel.add(labelFanart, "flowx,cell 0 3");

      JButton btnMarkExtrafanart = new JButton("");
      contentPanel.add(btnMarkExtrafanart, "cell 0 3");
      btnMarkExtrafanart.setMargin(BUTTON_MARGIN);
      btnMarkExtrafanart.setIcon(IconManager.CHECK_ALL);
      btnMarkExtrafanart.setToolTipText(BUNDLE.getString("image.extrafanart.markall")); //$NON-NLS-1$
      JButton btnUnMarkExtrafanart = new JButton("");
      contentPanel.add(btnUnMarkExtrafanart, "cell 0 3");
      btnUnMarkExtrafanart.setMargin(BUTTON_MARGIN);
      btnUnMarkExtrafanart.setIcon(IconManager.CLEAR_ALL);
      btnUnMarkExtrafanart.setToolTipText(BUNDLE.getString("image.extrafanart.unmarkall")); //$NON-NLS-1$
      btnUnMarkExtrafanart.addActionListener(arg0 -> {
        for (JToggleButton button : buttons) {
          if (button.getClientProperty("MediaArtworkExtrafanart") instanceof JCheckBox) {
            JCheckBox chkbx = (JCheckBox) button.getClientProperty("MediaArtworkExtrafanart");
            chkbx.setSelected(false);
          }
        }
      });
      btnMarkExtrafanart.addActionListener(arg0 -> {
        for (JToggleButton button : buttons) {
          if (button.getClientProperty("MediaArtworkExtrafanart") instanceof JCheckBox) {
            JCheckBox chkbx = (JCheckBox) button.getClientProperty("MediaArtworkExtrafanart");
            chkbx.setSelected(true);
          }
        }
      });
    }

    {
      JPanel infoPanel = new JPanel();
      infoPanel.setLayout(new MigLayout("", "[][grow]", "[]"));

      progressBar = new JProgressBar();
      infoPanel.add(progressBar, "cell 0 0");

      lblProgressAction = new JLabel("");
      infoPanel.add(lblProgressAction, "cell 1 0");

      setBottomInformationPanel(infoPanel);
    }
    {
      JButton cancelButton = new JButton(BUNDLE.getString("Button.cancel")); //$NON-NLS-1$
      Action actionCancel = new CancelAction();
      cancelButton.setAction(actionCancel);
      cancelButton.setActionCommand("Cancel");
      addButton(cancelButton);

      JButton btnAddFile = new JButton(BUNDLE.getString("Button.addfile")); //$NON-NLS-1$
      Action actionLocalFile = new LocalFileChooseAction();
      btnAddFile.setAction(actionLocalFile);
      addButton(btnAddFile);

      JButton okButton = new JButton(BUNDLE.getString("Button.ok")); //$NON-NLS-1$
      Action actionOK = new OkAction();
      okButton.setAction(actionOK);
      okButton.setActionCommand("OK");
      addDefaultButton(okButton);
    }

    task = new DownloadTask(ids, artworkScrapers);
    task.execute();
  }

  private void startProgressBar(String description) {
    lblProgressAction.setText(description);
    progressBar.setVisible(true);
    progressBar.setIndeterminate(true);
  }

  private void stopProgressBar() {
    lblProgressAction.setText("");
    progressBar.setVisible(false);
    progressBar.setIndeterminate(false);
  }

  @SuppressWarnings({ "unchecked", "rawtypes" })
  private void addImage(BufferedImage originalImage, final MediaArtwork artwork) {
    Point size = null;

    GridBagLayout gbl = new GridBagLayout();

    switch (type) {
      case FANART:
      case CLEARART:
      case THUMB:
      case DISC:
      case CHARACTERART:
        gbl.columnWidths = new int[] { 130 };
        gbl.rowHeights = new int[] { 180 };
        size = ImageUtils.calculateSize(300, 150, originalImage.getWidth(), originalImage.getHeight(), true);
        break;

      case BANNER:
      case LOGO:
      case CLEARLOGO:
        gbl.columnWidths = new int[] { 130 };
        gbl.rowHeights = new int[] { 120 };
        size = ImageUtils.calculateSize(300, 100, originalImage.getWidth(), originalImage.getHeight(), true);
        break;

      case POSTER:
      case KEYART:
      default:
        gbl.columnWidths = new int[] { 180 };
        gbl.rowHeights = new int[] { 270 };
        size = ImageUtils.calculateSize(150, 250, originalImage.getWidth(), originalImage.getHeight(), true);
        break;

    }

    gbl.columnWeights = new double[] { Double.MIN_VALUE };
    gbl.rowWeights = new double[] { Double.MIN_VALUE };
    JPanel imagePanel = new JPanel();
    imagePanel.setLayout(gbl);

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.fill = GridBagConstraints.BOTH;
    gbc.gridx = 0;
    gbc.gridy = 0;
    gbc.gridwidth = 3;
    gbc.insets = new Insets(5, 5, 5, 5);

    JToggleButton button = new JToggleButton();
    button.setBackground(Color.white);
    button.setUI(toggleButtonUI);
    button.setMargin(new Insets(10, 10, 10, 10));
    if (artwork.isAnimated()) {
      button.setText("");
      button.setBorder(BorderFactory.createLineBorder(Color.GREEN, 3));
    }
    else {
      ImageIcon imageIcon = new ImageIcon(
          Scalr.resize(originalImage, Scalr.Method.BALANCED, Scalr.Mode.AUTOMATIC, size.x, size.y, Scalr.OP_ANTIALIAS));
      button.setIcon(imageIcon);
    }
    button.putClientProperty("MediaArtwork", artwork);

    buttonGroup.add(button);
    buttons.add(button);
    imagePanel.add(button, gbc);

    gbc = new GridBagConstraints();
    gbc.gridx = 0;
    gbc.gridy = 1;
    gbc.anchor = GridBagConstraints.LAST_LINE_START;
    gbc.insets = new Insets(0, 5, 0, 0);

    JComboBox cb = null;
    if (!artwork.getImageSizes().isEmpty()) {
      cb = new JComboBox(artwork.getImageSizes().toArray());
    }
    else {
      cb = new JComboBox(new String[] { originalImage.getWidth() + "x" + originalImage.getHeight() });
    }
    button.putClientProperty("MediaArtworkSize", cb);
    imagePanel.add(cb, gbc);

    int row = 0;

    // should we provide an option for extrathumbs
    if (type == ImageType.FANART && extraThumbs != null) {
      row++;

      gbc = new GridBagConstraints();
      gbc.gridx = 1;
      gbc.gridy = row;
      gbc.anchor = GridBagConstraints.LINE_END;
      JLabel label = new JLabel("Extrathumb");
      imagePanel.add(label, gbc);

      gbc = new GridBagConstraints();
      gbc.gridx = 2;
      gbc.gridy = row;
      gbc.anchor = GridBagConstraints.LINE_END;
      JCheckBox chkbx = new JCheckBox();
      button.putClientProperty("MediaArtworkExtrathumb", chkbx);
      imagePanel.add(chkbx, gbc);
    }

    // should we provide an option for extrafanart
    if (type == ImageType.FANART && extraFanarts != null) {
      row++;

      gbc = new GridBagConstraints();
      gbc.gridx = 1;
      gbc.gridy = row;
      gbc.anchor = GridBagConstraints.LINE_END;
      JLabel label = new JLabel("Extrafanart");
      imagePanel.add(label, gbc);

      gbc = new GridBagConstraints();
      gbc.gridx = 2;
      gbc.gridy = row;
      gbc.anchor = GridBagConstraints.LINE_END;
      JCheckBox chkbx = new JCheckBox();
      button.putClientProperty("MediaArtworkExtrafanart", chkbx);
      imagePanel.add(chkbx, gbc);
    }

    /* show image button */
    gbc.gridx = 0;
    gbc.gridy++;
    gbc.anchor = GridBagConstraints.LAST_LINE_START;
    gbc.gridwidth = 3;
    gbc.insets = new Insets(0, 0, 0, 0);

    LinkLabel lblShowImage = new LinkLabel(BUNDLE.getString("image.showoriginal"));
    lblShowImage.addActionListener(e -> {
      ImagePreviewDialog dialog = new ImagePreviewDialog(artwork.getDefaultUrl());
      dialog.setVisible(true);
    });
    imagePanel.add(lblShowImage, gbc);

    panelImages.add(imagePanel);
    panelImages.validate();
    panelImages.getParent().validate();
  }

  private void downloadAndPreviewImage(String url) {
    Runnable task = () -> {
      try {
        final MediaArtwork art;
        switch (type) {
          case BANNER:
            art = new MediaArtwork("", MediaArtworkType.BANNER);
            break;
          case CLEARART:
            art = new MediaArtwork("", MediaArtworkType.CLEARART);
            break;
          case DISC:
            art = new MediaArtwork("", MediaArtworkType.DISC);
            break;
          case FANART:
            art = new MediaArtwork("", MediaArtworkType.BACKGROUND);
            break;
          case LOGO:
            art = new MediaArtwork("", MediaArtworkType.LOGO);
            break;
          case CLEARLOGO:
            art = new MediaArtwork("", MediaArtworkType.CLEARLOGO);
            break;
          case CHARACTERART:
            art = new MediaArtwork("", MediaArtworkType.CHARACTERART);
            break;
          case POSTER:
            art = new MediaArtwork("", MediaArtworkType.POSTER);
            break;
          case SEASON_POSTER:
            art = new MediaArtwork("", MediaArtworkType.SEASON_POSTER);
            break;
          case SEASON_BANNER:
            art = new MediaArtwork("", MediaArtworkType.SEASON_BANNER);
            break;
          case SEASON_THUMB:
            art = new MediaArtwork("", MediaArtworkType.SEASON_THUMB);
            break;
          case THUMB:
            art = new MediaArtwork("", MediaArtworkType.THUMB);
            break;
          case KEYART:
            art = new MediaArtwork("", MediaArtworkType.KEYART);
            break;

          default:
            return;
        }
        art.setDefaultUrl(url);
        art.setPreviewUrl(url);

        Url url1 = new Url(art.getPreviewUrl());
        final BufferedImage bufferedImage = ImageUtils.createImage(url1.getBytesWithRetry(5));

        SwingUtilities.invokeLater(() -> {
          addImage(bufferedImage, art);

          // scroll down
          JScrollBar vertical = scrollPane.getVerticalScrollBar();
          vertical.setValue(vertical.getMaximum());
        });
        tfImageUrl.setText("");
      }
      catch (Exception e) {
        LOGGER.error("could not download manually entered image url: {} - {}", tfImageUrl.getText(), e.getMessage());
      }
    };
    task.run();
  }

  /**
   * call a new image chooser dialog without extrathumbs and extrafanart usage.
* this method also checks if there are valid IDs for scraping * * @param parent * the parent of this dialog * @param ids * the ids * @param type * the type * @param artworkScrapers * the artwork providers * @param mediaType * the media for for which artwork has to be chosen */ public static String chooseImage(JDialog parent, final Map ids, ImageType type, List artworkScrapers, MediaType mediaType) { return chooseImage(parent, ids, type, artworkScrapers, null, null, mediaType); } /** * call a new image chooser dialog without extrathumbs and extrafanart usage.
* this method also checks if there are valid IDs for scraping * * @param ids * the ids * @param type * the type * @param artworkScrapers * the artwork providers * @param mediaType * the media for for which artwork has to be chosen */ public static String chooseImage(final Map ids, ImageType type, List artworkScrapers, MediaType mediaType) { return chooseImage(ids, type, artworkScrapers, null, null, mediaType); } /** * call a new image chooser dialog with extrathumbs and extrafanart usage.
* this method also checks if there are valid IDs for scraping * * @param parent * the parent of this dialog * @param ids * the ids * @param type * the type * @param artworkScrapers * the artwork providers * @param extraThumbs * the extra thumbs * @param extraFanarts * the extra fanarts * @param mediaType * the media for for which artwork has to be chosen */ public static String chooseImage(JDialog parent, final Map ids, ImageType type, List artworkScrapers, List extraThumbs, List extraFanarts, MediaType mediaType) { if (ids.isEmpty()) { return ""; } ImageLabel lblImage = new ImageLabel(); ImageChooserDialog dialog = new ImageChooserDialog(parent, ids, type, artworkScrapers, lblImage, extraThumbs, extraFanarts, mediaType); dialog.setLocationRelativeTo(MainWindow.getActiveInstance()); dialog.setVisible(true); return lblImage.getImageUrl(); } /** * call a new image chooser dialog with extrathumbs and extrafanart usage.
* this method also checks if there are valid IDs for scraping * * @param ids * the ids * @param type * the type * @param artworkScrapers * the artwork providers * @param extraThumbs * the extra thumbs * @param extraFanarts * the extra fanarts * @param mediaType * the media for for which artwork has to be chosen */ public static String chooseImage(final Map ids, ImageType type, List artworkScrapers, List extraThumbs, List extraFanarts, MediaType mediaType) { if (ids.isEmpty()) { return ""; } ImageLabel lblImage = new ImageLabel(); ImageChooserDialog dialog = new ImageChooserDialog(ids, type, artworkScrapers, lblImage, extraThumbs, extraFanarts, mediaType); dialog.setLocationRelativeTo(MainWindow.getActiveInstance()); dialog.setVisible(true); return lblImage.getImageUrl(); } private class OkAction extends AbstractAction { private static final long serialVersionUID = -1255049344169945137L; public OkAction() { putValue(NAME, BUNDLE.getString("Button.ok")); //$NON-NLS-1$ putValue(SHORT_DESCRIPTION, BUNDLE.getString("image.seteselected")); //$NON-NLS-1$ putValue(SMALL_ICON, IconManager.APPLY_INV); putValue(LARGE_ICON_KEY, IconManager.APPLY_INV); } @Override public void actionPerformed(ActionEvent e) { MediaArtwork artwork = null; ImageSizeAndUrl resolution = null; // get selected button for (JToggleButton button : buttons) { if (button.isSelected()) { Object clientProperty = button.getClientProperty("MediaArtwork"); if (clientProperty instanceof MediaArtwork) { artwork = (MediaArtwork) clientProperty; clientProperty = button.getClientProperty("MediaArtworkSize"); // try to get the size if (clientProperty instanceof JComboBox) { @SuppressWarnings("rawtypes") JComboBox cb = (JComboBox) clientProperty; if (cb.getSelectedItem() instanceof ImageSizeAndUrl) { resolution = (ImageSizeAndUrl) cb.getSelectedItem(); } } break; } } } // nothing selected if (artwork == null) { JOptionPane.showMessageDialog(null, BUNDLE.getString("image.noneselected")); //$NON-NLS-1$ return; } if (artwork != null) { imageLabel.clearImage(); if (resolution != null) { imageLabel.setImageUrl(resolution.getUrl()); } else { imageLabel.setImageUrl(artwork.getDefaultUrl()); } } // extrathumbs if (type == ImageType.FANART && extraThumbs != null) { processExtraThumbs(); } // extrafanart if (type == ImageType.FANART && extraFanarts != null) { processExtraFanart(); } task.cancel(true); setVisible(false); } /** * Process extra thumbs. */ private void processExtraThumbs() { extraThumbs.clear(); // get extrathumbs for (JToggleButton button : buttons) { if (button.getClientProperty("MediaArtworkExtrathumb") instanceof JCheckBox && button.getClientProperty("MediaArtwork") instanceof MediaArtwork && button.getClientProperty("MediaArtworkSize") instanceof JComboBox) { JCheckBox chkbx = (JCheckBox) button.getClientProperty("MediaArtworkExtrathumb"); if (chkbx.isSelected()) { MediaArtwork artwork = (MediaArtwork) button.getClientProperty("MediaArtwork"); @SuppressWarnings("rawtypes") JComboBox cb = (JComboBox) button.getClientProperty("MediaArtworkSize"); if (cb.getSelectedItem() instanceof ImageSizeAndUrl) { ImageSizeAndUrl size = (ImageSizeAndUrl) cb.getSelectedItem(); if (size != null) { extraThumbs.add(size.getUrl()); } else { extraThumbs.add(artwork.getDefaultUrl()); } } else if (cb.getSelectedItem() instanceof String) { extraThumbs.add(artwork.getDefaultUrl()); } } } } } /** * Process extra fanart. */ private void processExtraFanart() { extraFanarts.clear(); // get extrafanart for (JToggleButton button : buttons) { if (button.getClientProperty("MediaArtworkExtrafanart") instanceof JCheckBox && button.getClientProperty("MediaArtwork") instanceof MediaArtwork && button.getClientProperty("MediaArtworkSize") instanceof JComboBox) { JCheckBox chkbx = (JCheckBox) button.getClientProperty("MediaArtworkExtrafanart"); if (chkbx.isSelected()) { MediaArtwork artwork = (MediaArtwork) button.getClientProperty("MediaArtwork"); @SuppressWarnings("rawtypes") JComboBox cb = (JComboBox) button.getClientProperty("MediaArtworkSize"); if (cb.getSelectedItem() instanceof ImageSizeAndUrl) { ImageSizeAndUrl size = (ImageSizeAndUrl) cb.getSelectedItem(); if (size != null) { extraFanarts.add(size.getUrl()); } else { extraFanarts.add(artwork.getDefaultUrl()); } } else if (cb.getSelectedItem() instanceof String) { extraFanarts.add(artwork.getDefaultUrl()); } } } } } } private class CancelAction extends AbstractAction { private static final long serialVersionUID = 403327079655572423L; public CancelAction() { putValue(NAME, BUNDLE.getString("Button.cancel")); //$NON-NLS-1$ putValue(SHORT_DESCRIPTION, BUNDLE.getString("Button.cancel")); //$NON-NLS-1$ putValue(SMALL_ICON, IconManager.CANCEL_INV); putValue(LARGE_ICON_KEY, IconManager.CANCEL_INV); } @Override public void actionPerformed(ActionEvent e) { task.cancel(true); setVisible(false); } } private class DownloadTask extends SwingWorker { private Map ids; private List artworkScrapers; private boolean imagesFound = false; public DownloadTask(Map ids, List artworkScrapers) { this.ids = ids; this.artworkScrapers = artworkScrapers; } @Override public Void doInBackground() { if (ids.isEmpty()) { JOptionPane.showMessageDialog(null, BUNDLE.getString("image.download.noid")); //$NON-NLS-1$ return null; } SwingUtilities.invokeLater(() -> { startProgressBar(BUNDLE.getString("image.download.progress")); //$NON-NLS-1$ }); if (artworkScrapers == null || artworkScrapers.isEmpty()) { return null; } // open a thread pool to parallel download the images ThreadPoolExecutor pool = new ThreadPoolExecutor(5, 10, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); pool.allowCoreThreadTimeOut(true); ExecutorCompletionService service = new ExecutorCompletionService<>(pool); // get images from all artworkproviders for (MediaScraper scraper : artworkScrapers) { try { IMediaArtworkProvider artworkProvider = (IMediaArtworkProvider) scraper.getMediaProvider(); MediaScrapeOptions options = new MediaScrapeOptions(mediaType); if (mediaType == MediaType.MOVIE || mediaType == MediaType.MOVIE_SET) { options.setLanguage(MovieModuleManager.SETTINGS.getImageScraperLanguage().toLocale()); options.setCountry(MovieModuleManager.SETTINGS.getCertificationCountry()); options.setFanartSize(MovieModuleManager.SETTINGS.getImageFanartSize()); options.setPosterSize(MovieModuleManager.SETTINGS.getImagePosterSize()); } else if (mediaType == MediaType.TV_SHOW) { options.setLanguage(TvShowModuleManager.SETTINGS.getScraperLanguage().toLocale()); options.setCountry(TvShowModuleManager.SETTINGS.getCertificationCountry()); } else { continue; } switch (type) { case POSTER: options.setArtworkType(MediaArtworkType.POSTER); break; case FANART: options.setArtworkType(MediaArtworkType.BACKGROUND); break; case BANNER: options.setArtworkType(MediaArtworkType.BANNER); break; case SEASON_POSTER: options.setArtworkType(MediaArtworkType.SEASON_POSTER); break; case SEASON_BANNER: options.setArtworkType(MediaArtworkType.SEASON_BANNER); break; case SEASON_THUMB: options.setArtworkType(MediaArtworkType.SEASON_THUMB); break; case CLEARART: options.setArtworkType(MediaArtworkType.CLEARART); break; case DISC: options.setArtworkType(MediaArtworkType.DISC); break; case LOGO: options.setArtworkType(MediaArtworkType.LOGO); break; case CLEARLOGO: options.setArtworkType(MediaArtworkType.CLEARLOGO); break; case CHARACTERART: options.setArtworkType(MediaArtworkType.CHARACTERART); break; case KEYART: options.setArtworkType(MediaArtworkType.KEYART); break; case THUMB: options.setArtworkType(MediaArtworkType.THUMB); break; } // populate ids for (Entry entry : ids.entrySet()) { Object v = entry.getValue(); if (v != null) { options.setId(entry.getKey(), v.toString()); } } // get the artwork List artwork = artworkProvider.getArtwork(options); if (artwork == null) { continue; } // display all images for (MediaArtwork art : artwork) { if (isCancelled()) { return null; } try { Callable callable = () -> { Url url = new Url(art.getPreviewUrl()); BufferedImage bufferedImage = ImageUtils.createImage(url.getBytesWithRetry(5)); DownloadChunk chunk = new DownloadChunk(); chunk.artwork = art; chunk.image = bufferedImage; return chunk; }; service.submit(callable); } catch (Exception e) { LOGGER.error("DownloadTask displaying: {}", e.getMessage()); } } } catch (ScrapeException e) { LOGGER.error("getArtwork", e); MessageDialog.showExceptionWindow(e); } catch (MissingIdException e) { LOGGER.debug("could not fetch artwork: {}", e.getIds()); } catch (Exception e) { if (e instanceof InterruptedException || e instanceof InterruptedIOException) { // NOSONAR // shutdown the pool pool.getQueue().clear(); pool.shutdown(); return null; } LOGGER.error("could not process artwork downloading - {}", e.getMessage()); } } // end foreach scraper // wait for all downloads to finish pool.shutdown(); while (!pool.isTerminated()) { try { final Future future = service.take(); publish(future.get()); imagesFound = true; } catch (InterruptedException e) { // NOSONAR return null; } catch (ExecutionException e) { LOGGER.error("ThreadPool imageChooser: Error getting result! - {}", e); } } return null; } @Override protected void process(List chunks) { for (DownloadChunk chunk : chunks) { addImage(chunk.image, chunk.artwork); } } @Override public void done() { if (!imagesFound) { JLabel lblNothingFound = new JLabel(BUNDLE.getString("image.download.nothingfound"));//$NON-NLS-1$ TmmFontHelper.changeFont(lblNothingFound, 1.33); panelImages.add(lblNothingFound); panelImages.validate(); panelImages.getParent().validate(); } SwingUtilities.invokeLater(ImageChooserDialog.this::stopProgressBar); } } private class DownloadChunk { private BufferedImage image; private MediaArtwork artwork; } private class LocalFileChooseAction extends AbstractAction { private static final long serialVersionUID = -1178325861474276709L; public LocalFileChooseAction() { putValue(NAME, BUNDLE.getString("image.choose.file")); //$NON-NLS-1$ putValue(SHORT_DESCRIPTION, BUNDLE.getString("image.choose.file")); //$NON-NLS-1$ putValue(SMALL_ICON, IconManager.FILE_OPEN_INV); putValue(LARGE_ICON_KEY, IconManager.FILE_OPEN_INV); } @Override public void actionPerformed(ActionEvent e) { String path = TmmProperties.getInstance().getProperty(DIALOG_ID + ".path"); Path file = TmmUIHelper.selectFile(BUNDLE.getString("image.choose"), path); //$NON-NLS-1$ if (file != null && Utils.isRegularFile(file)) { String fileName = file.toAbsolutePath().toString(); imageLabel.clearImage(); imageLabel.setImageUrl("file:/" + fileName); task.cancel(true); TmmProperties.getInstance().putProperty(DIALOG_ID + ".path", fileName); setVisible(false); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy