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

org.tinymediamanager.ui.moviesets.dialogs.MovieSetChooserDialog 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.moviesets.dialogs;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

import org.jdesktop.beansbinding.AutoBinding;
import org.jdesktop.beansbinding.AutoBinding.UpdateStrategy;
import org.jdesktop.beansbinding.BeanProperty;
import org.jdesktop.beansbinding.BindingGroup;
import org.jdesktop.beansbinding.Bindings;
import org.jdesktop.observablecollections.ObservableCollections;
import org.jdesktop.swingbinding.JTableBinding;
import org.jdesktop.swingbinding.SwingBindings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tinymediamanager.core.movie.MovieModuleManager;
import org.tinymediamanager.core.movie.entities.Movie;
import org.tinymediamanager.core.movie.entities.MovieSet;
import org.tinymediamanager.scraper.MediaScraper;
import org.tinymediamanager.scraper.MediaSearchOptions;
import org.tinymediamanager.scraper.MediaSearchResult;
import org.tinymediamanager.scraper.ScraperType;
import org.tinymediamanager.scraper.entities.MediaType;
import org.tinymediamanager.scraper.mediaprovider.IMovieSetMetadataProvider;
import org.tinymediamanager.ui.IconManager;
import org.tinymediamanager.ui.TmmFontHelper;
import org.tinymediamanager.ui.components.ImageLabel;
import org.tinymediamanager.ui.components.ReadOnlyTextPane;
import org.tinymediamanager.ui.components.TmmSplitPane;
import org.tinymediamanager.ui.components.table.TmmTable;
import org.tinymediamanager.ui.dialogs.TmmDialog;
import org.tinymediamanager.ui.moviesets.MovieSetChooserModel;
import org.tinymediamanager.ui.moviesets.MovieSetChooserModel.MovieInSet;

import net.miginfocom.swing.MigLayout;

/**
 * The Class MovieSetChooserPanel.
 * 
 * @author Manuel Laggner
 */
public class MovieSetChooserDialog extends TmmDialog implements ActionListener {
  private static final long          serialVersionUID = -1023959850452480592L;
  private static final Logger        LOGGER           = LoggerFactory.getLogger(MovieSetChooserDialog.class);

  private MovieSet                   movieSetToScrape;
  private List movieSetsFound   = ObservableCollections.observableList(new ArrayList<>());
  private boolean                    continueQueue    = true;

  private JLabel                     lblProgressAction;
  private JProgressBar               progressBar;
  private JTextField                 tfMovieSetName;
  private JTable                     tableMovieSets;
  private JLabel                     lblMovieSetName;
  private ImageLabel                 lblMovieSetPoster;
  private JTable                     tableMovies;
  private JCheckBox                  cbAssignMovies;
  private JButton                    btnOk;
  private JTextPane                  tpPlot;

  /**
   * Instantiates a new movie set chooser panel.
   * 
   * @param movieSet
   *          the movie set
   */
  public MovieSetChooserDialog(MovieSet movieSet, boolean inQueue) {
    super(BUNDLE.getString("movieset.search"), "movieSetChooser"); //$NON-NLS-1$

    movieSetToScrape = movieSet;

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

      // also attach the actionlistener to the textfield to trigger the search on enter in the textfield
      Action searchAction = new SearchAction();

      tfMovieSetName = new JTextField();
      tfMovieSetName.addActionListener(searchAction);
      panelHeader.add(tfMovieSetName, "cell 0 0,growx");
      tfMovieSetName.setColumns(10);

      JButton btnSearch = new JButton(searchAction);
      panelHeader.add(btnSearch, "cell 1 0");

      setTopIformationPanel(panelHeader);
    }
    {
      JPanel panelContent = new JPanel();
      getContentPane().add(panelContent, BorderLayout.CENTER);
      panelContent.setLayout(new MigLayout("", "[950lp,grow]", "[500,grow]"));

      JSplitPane splitPane = new TmmSplitPane();
      splitPane.setResizeWeight(0.5);
      panelContent.add(splitPane, "cell 0 0,grow");
      {
        JPanel panelResults = new JPanel();
        panelResults.setLayout(new MigLayout("", "[200lp:300lp,grow]", "[300lp,grow]"));
        JScrollPane panelSearchResults = new JScrollPane();
        panelResults.add(panelSearchResults, "cell 0 0,grow");
        splitPane.setLeftComponent(panelResults);
        {
          tableMovieSets = new TmmTable();
          panelSearchResults.setViewportView(tableMovieSets);
          tableMovieSets.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
          ListSelectionModel rowSM = tableMovieSets.getSelectionModel();
          rowSM.addListSelectionListener(e -> {
            // Ignore extra messages.
            if (e.getValueIsAdjusting())
              return;

            ListSelectionModel lsm = (ListSelectionModel) e.getSource();
            if (!lsm.isSelectionEmpty()) {
              int selectedRow = lsm.getMinSelectionIndex();
              selectedRow = tableMovieSets.convertRowIndexToModel(selectedRow);
              try {
                MovieSetChooserModel model = movieSetsFound.get(selectedRow);
                if (model != MovieSetChooserModel.emptyResult && !model.isScraped()) {
                  ScrapeTask task = new ScrapeTask(model);
                  task.execute();

                }
              }
              catch (Exception ex) {
                LOGGER.warn(ex.getMessage());
              }
            }
          });
          tableMovieSets.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
              if (e.getClickCount() >= 2 && !e.isConsumed() && e.getButton() == MouseEvent.BUTTON1) {
                actionPerformed(new ActionEvent(btnOk, ActionEvent.ACTION_PERFORMED, "Save"));
              }
            }
          });
        }
      }
      {
        JPanel panelSearchDetail = new JPanel();
        splitPane.setRightComponent(panelSearchDetail);
        panelSearchDetail.setLayout(new MigLayout("", "[150lp,grow 60][450lp,grow]", "[][250lp,grow][150lp][]"));
        {
          lblMovieSetName = new JLabel("");
          TmmFontHelper.changeFont(lblMovieSetName, 1.166, Font.BOLD);
          panelSearchDetail.add(lblMovieSetName, "cell 0 0 2 1,growx");
        }
        {
          lblMovieSetPoster = new ImageLabel();
          panelSearchDetail.add(lblMovieSetPoster, "cell 0 1,grow");
        }
        {
          JScrollPane scrollPane = new JScrollPane();
          panelSearchDetail.add(scrollPane, "cell 1 1,grow");

          tpPlot = new ReadOnlyTextPane();
          scrollPane.setViewportView(tpPlot);
        }
        {
          JScrollPane scrollPane = new JScrollPane();
          panelSearchDetail.add(scrollPane, "cell 0 2 2 1,grow");

          tableMovies = new TmmTable();
          scrollPane.setViewportView(tableMovies);
        }
        {
          cbAssignMovies = new JCheckBox(BUNDLE.getString("movieset.movie.assign")); //$NON-NLS-1$
          cbAssignMovies.setSelected(true);
          panelSearchDetail.add(cbAssignMovies, "cell 0 3 2 1,growx,aligny top");
        }
      }
    }

    {
      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);
    }
    {
      if (inQueue) {
        JButton btnAbort = new JButton(BUNDLE.getString("Button.abortqueue")); //$NON-NLS-1$
        btnAbort.setActionCommand("Abort");
        btnAbort.setToolTipText(BUNDLE.getString("Button.abortqueue")); //$NON-NLS-1$
        btnAbort.setIcon(IconManager.STOP_INV);
        btnAbort.addActionListener(this);
        addButton(btnAbort);
      }

      JButton btnCancel = new JButton(BUNDLE.getString("Button.cancel")); //$NON-NLS-1$
      btnCancel.setActionCommand("Cancel");
      btnCancel.setToolTipText(BUNDLE.getString("Button.cancel")); //$NON-NLS-1$
      btnCancel.setIcon(IconManager.CANCEL_INV);
      btnCancel.addActionListener(this);
      addButton(btnCancel);

      btnOk = new JButton(BUNDLE.getString("Button.ok")); //$NON-NLS-1$
      btnOk.setActionCommand("Save");
      btnOk.setToolTipText(BUNDLE.getString("Button.ok")); //$NON-NLS-1$
      btnOk.setIcon(IconManager.APPLY_INV);
      btnOk.addActionListener(this);
      addDefaultButton(btnOk);
    }

    bindingGroup = initDataBindings();

    // adjust table columns
    tableMovies.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    tableMovies.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);

    tableMovieSets.getColumnModel().getColumn(0).setHeaderValue(BUNDLE.getString("chooser.searchresult"));
    tfMovieSetName.setText(movieSet.getTitle());
    searchMovie();

  }

  private void searchMovie() {
    SearchTask task = new SearchTask(tfMovieSetName.getText());
    task.execute();
  }

  private class SearchTask extends SwingWorker {
    private String searchTerm;

    public SearchTask(String searchTerm) {
      this.searchTerm = searchTerm;
    }

    @Override
    public Void doInBackground() {
      startProgressBar(BUNDLE.getString("chooser.searchingfor") + " " + searchTerm); //$NON-NLS-1$
      try {
        List sets = MediaScraper.getMediaScrapers(ScraperType.MOVIE_SET);
        if (sets != null && sets.size() > 0) {
          MediaScraper first = sets.get(0); // just get first
          IMovieSetMetadataProvider mp = (IMovieSetMetadataProvider) first.getMediaProvider();

          MediaSearchOptions options = new MediaSearchOptions(MediaType.MOVIE_SET, searchTerm);
          options.setLanguage(MovieModuleManager.SETTINGS.getScraperLanguage().toLocale());
          List movieSets = mp.search(options);
          movieSetsFound.clear();
          if (movieSets.size() == 0) {
            movieSetsFound.add(MovieSetChooserModel.emptyResult);
          }
          else {
            for (MediaSearchResult collection : movieSets) {
              MovieSetChooserModel model = new MovieSetChooserModel(collection);
              movieSetsFound.add(model);
            }
          }
        }

        if (!movieSetsFound.isEmpty()) {
          tableMovieSets.setRowSelectionInterval(0, 0); // select first row
        }
      }
      catch (Exception e1) {
        LOGGER.warn("SearchTask", e1);
      }

      return null;
    }

    @Override
    public void done() {
      stopProgressBar();
    }
  }

  private class SearchAction extends AbstractAction {
    private static final long serialVersionUID = -6561883838396668177L;

    SearchAction() {
      putValue(NAME, BUNDLE.getString("Button.search")); //$NON-NLS-1$
      putValue(SHORT_DESCRIPTION, BUNDLE.getString("movieset.search")); //$NON-NLS-1$
      putValue(SMALL_ICON, IconManager.SEARCH_INV);
      putValue(LARGE_ICON_KEY, IconManager.SEARCH_INV);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      searchMovie();
    }
  }

  @Override
  public void actionPerformed(ActionEvent arg0) {
    if ("Cancel".equals(arg0.getActionCommand())) {
      // cancel
      setVisible(false);
    }

    if ("Save".equals(arg0.getActionCommand())) {
      // save it
      int row = tableMovieSets.getSelectedRow();
      if (row >= 0) {
        MovieSetChooserModel model = movieSetsFound.get(row);
        if (model != MovieSetChooserModel.emptyResult) {
          movieSetToScrape.setTitle(model.getName());
          movieSetToScrape.setPlot(model.getOverview());
          // movieSetToScrape.setArtworkUrl(model.getPosterUrl(), MediaFileType.POSTER);
          // movieSetToScrape.setArtworkUrl(model.getFanartUrl(), MediaFileType.FANART);
          movieSetToScrape.setTmdbId(model.getTmdbId());
          movieSetToScrape.saveToDb();

          // assign movies
          if (cbAssignMovies.isSelected()) {
            movieSetToScrape.removeAllMovies();
            for (int i = 0; i < model.getMovies().size(); i++) {
              MovieInSet movieInSet = model.getMovies().get(i);
              Movie movie = movieInSet.getMovie();
              if (movie == null) {
                continue;
              }

              // check if the found movie contains a matching set
              if (movie.getMovieSet() != null) {
                // unassign movie from set
                MovieSet mSet = movie.getMovieSet();
                mSet.removeMovie(movie, true);
              }

              movie.setMovieSet(movieSetToScrape);
              movie.writeNFO();
              movie.saveToDb();
              movieSetToScrape.addMovie(movie);
            }

            // and finally save assignments
            movieSetToScrape.saveToDb();
          }
          // get images?
          if (MovieModuleManager.SETTINGS.getMovieScraperMetadataConfig().isArtwork()) {
            // get artwork asynchronous
            model.startArtworkScrapeTask(movieSetToScrape, MovieModuleManager.SETTINGS.getMovieScraperMetadataConfig());
          }
        }
        setVisible(false);
      }
    }

    // Abort queue
    if ("Abort".equals(arg0.getActionCommand())) {
      continueQueue = false;
      setVisible(false);
    }
  }

  private class ScrapeTask extends SwingWorker {
    private MovieSetChooserModel model;

    ScrapeTask(MovieSetChooserModel model) {
      this.model = model;
    }

    @Override
    public Void doInBackground() {
      startProgressBar(BUNDLE.getString("chooser.scrapeing") + " " + model.getName()); //$NON-NLS-1$

      // disable ok button as long as its scraping
      btnOk.setEnabled(false);
      model.scrapeMetadata();
      btnOk.setEnabled(true);

      return null;
    }

    @Override
    public void done() {
      stopProgressBar();
    }
  }

  private void startProgressBar(final String description) {
    SwingUtilities.invokeLater(() -> {
      lblProgressAction.setText(description);
      progressBar.setVisible(true);
      progressBar.setIndeterminate(true);
    });
  }

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

  /**
   * Shows the dialog and returns whether the work on the queue should be continued.
   * 
   * @return true, if successful
   */
  public boolean showDialog() {
    setVisible(true);
    return continueQueue;
  }

  protected BindingGroup initDataBindings() {
    JTableBinding, JTable> jTableBinding = SwingBindings.createJTableBinding(UpdateStrategy.READ,
        movieSetsFound, tableMovieSets);
    //
    BeanProperty movieSetChooserModelBeanProperty = BeanProperty.create("name");
    jTableBinding.addColumnBinding(movieSetChooserModelBeanProperty).setEditable(false);
    //
    jTableBinding.bind();
    //
    BeanProperty> jTableBeanProperty = BeanProperty.create("selectedElement.movies");
    JTableBinding jTableBinding_1 = SwingBindings.createJTableBinding(UpdateStrategy.READ, tableMovieSets,
        jTableBeanProperty, tableMovies);
    //
    BeanProperty movieInSetBeanProperty = BeanProperty.create("name");
    jTableBinding_1.addColumnBinding(movieInSetBeanProperty).setColumnName("Movie").setEditable(false);
    //
    BeanProperty movieInSetBeanProperty_2 = BeanProperty.create("movie.title");
    jTableBinding_1.addColumnBinding(movieInSetBeanProperty_2).setColumnName("matched movie").setEditable(false);
    //
    jTableBinding_1.bind();
    //
    BeanProperty jTableBeanProperty_1 = BeanProperty.create("selectedElement.name");
    BeanProperty jLabelBeanProperty = BeanProperty.create("text");
    AutoBinding autoBinding = Bindings.createAutoBinding(UpdateStrategy.READ, tableMovieSets, jTableBeanProperty_1,
        lblMovieSetName, jLabelBeanProperty);
    autoBinding.bind();
    //
    BeanProperty jTableBeanProperty_2 = BeanProperty.create("selectedElement.posterUrl");
    BeanProperty imageLabelBeanProperty = BeanProperty.create("imageUrl");
    AutoBinding autoBinding_1 = Bindings.createAutoBinding(UpdateStrategy.READ, tableMovieSets,
        jTableBeanProperty_2, lblMovieSetPoster, imageLabelBeanProperty);
    autoBinding_1.bind();
    //
    BeanProperty jTableBeanProperty_3 = BeanProperty.create("selectedElement.overview");
    BeanProperty readOnlyTextPaneBeanProperty = BeanProperty.create("text");
    AutoBinding autoBinding_2 = Bindings.createAutoBinding(UpdateStrategy.READ, tableMovieSets,
        jTableBeanProperty_3, tpPlot, readOnlyTextPaneBeanProperty);
    autoBinding_2.bind();
    //
    BindingGroup bindingGroup = new BindingGroup();
    //
    bindingGroup.addBinding(jTableBinding);
    bindingGroup.addBinding(jTableBinding_1);
    bindingGroup.addBinding(autoBinding);
    bindingGroup.addBinding(autoBinding_1);
    bindingGroup.addBinding(autoBinding_2);
    return bindingGroup;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy