/**
   * Change the item.
   *
   * @param old DOCUMENT_ME
   * @param sNewName DOCUMENT_ME
   * @return new album
   * @throws JajukException the jajuk exception
   */
  public Album changeAlbumName(Album old, String sNewName) throws JajukException {
    // check there is actually a change
    if (old.getName2().equals(sNewName)) {
      return old;
    }

    // check up front as later the state of the track is already changed
    boolean bQueueUpdateRequired = false;
    if (QueueModel.getPlayingFile() != null
        && QueueModel.getPlayingFile().getTrack().getAlbum().equals(old)) {
      bQueueUpdateRequired = true;
    }

    Album newItem = registerAlbum(sNewName, old.getDiscID());
    // re apply old properties from old item
    newItem.cloneProperties(old);

    // update tracks
    for (Track track : TrackManager.getInstance().getTracks()) {
      if (track.getAlbum().equals(old)) {
        TrackManager.getInstance().changeTrackAlbum(track, sNewName, null);
      }
    }

    // if current track album name is changed, notify it
    if (bQueueUpdateRequired) {
      ObservationManager.notify(new JajukEvent(JajukEvents.ALBUM_CHANGED));
    }

    // remove old item
    removeItem(old);

    return newItem;
  }
 /* (non-Javadoc)
  * @see org.jdesktop.swingx.decorator.HighlightPredicate#isHighlighted(java.awt.Component, org.jdesktop.swingx.decorator.ComponentAdapter)
  */
 public boolean isHighlighted(Component renderer, ComponentAdapter adapter) {
   if (QueueModel.isStopped()) {
     return false;
   }
   Item item = model.getItemAt(adapter.row);
   if (item instanceof File && QueueModel.getPlayingFile() != null) {
     File file = (File) item;
     if (file.equals(QueueModel.getPlayingFile())) {
       return true;
     }
   } else if (item instanceof Track) {
     List<File> files = ((Track) item).getFiles();
     if (files.contains(QueueModel.getPlayingFile())) {
       return true;
     }
   }
   return false;
 }
  /**
   * Invoked when an action occurs.
   *
   * @param evt
   */
  @Override
  public void perform(ActionEvent evt) {

    boolean b = Conf.getBoolean(Const.CONF_STATE_REPEAT);

    UtilGUI.setRepeatSingleGui(!b);
    QueueModel.setRepeatModeToAll(false);

    if (!b) { // enabled button
      // if FIFO is not void, repeat over current item
      StackItem item = QueueModel.getCurrentItem();
      if (item != null) {
        item.setRepeat(true);
      }
    } else { // disable repeat mode
      if (Conf.getBoolean(Const.CONF_DROP_PLAYED_TRACKS_FROM_QUEUE)) {
        // remove tracks before current position
        QueueModel.remove(0, QueueModel.getIndex() - 1);
        QueueModel.setIndex(0); // select first track
      }
    }
    // computes planned tracks
    QueueModel.computesPlanned(false);
    // Refresh Queue View
    ObservationManager.notify(new JajukEvent(JajukEvents.QUEUE_NEED_REFRESH));
  }
 /**
  * Unmount the device with ejection.
  *
  * @param bEjection set whether the device must be ejected
  * @param bUIRefresh set whether the UI should be refreshed
  */
 public void unmount(final boolean bEjection, final boolean bUIRefresh) {
   // look to see if the device is already mounted
   if (!bMounted) {
     Messages.showErrorMessage(125); // already unmounted
     return;
   }
   // ask fifo if it doens't use any track from this device
   if (!QueueModel.canUnmount(this)) {
     Messages.showErrorMessage(121);
     return;
   }
   bMounted = false;
   if (bUIRefresh) {
     ObservationManager.notify(new JajukEvent(JajukEvents.DEVICE_UNMOUNT));
   }
 }
  /** Refresh last fm collection tabs. */
  private void refreshLastFMCollectionTabs() {
    String newArtist = null;
    File current = QueueModel.getPlayingFile();
    if (current != null) {
      newArtist = current.getTrack().getArtist().getName2();
    }
    // if none track playing
    if (current == null
        // Last.FM infos is disable
        || !Conf.getBoolean(Const.CONF_LASTFM_INFO)
        // None internet access option is set
        || Conf.getBoolean(Const.CONF_NETWORK_NONE_INTERNET_ACCESS)
        // If unknown artist
        || (newArtist == null || newArtist.equals(Messages.getString(UNKNOWN_ARTIST)))) {
      // Set empty panels
      SwingUtilities.invokeLater(
          new Runnable() {
            @Override
            public void run() {
              stopAllBusyLabels();
              tabs.setComponentAt(3, new JLabel(Messages.getString("SuggestionView.7")));
              tabs.setComponentAt(4, new JLabel(Messages.getString("SuggestionView.7")));
            }
          });
      return;
    }
    // Check if artist changed, otherwise, just leave
    if (newArtist.equals(this.artist)) {
      return;
    }
    // Save current artist
    artist = newArtist;
    // Display a busy panel in the mean-time
    SwingUtilities.invokeLater(
        new Runnable() {
          @Override
          public void run() {
            JXBusyLabel busy1 = new JXBusyLabel();
            busy1.setBusy(true);
            JXBusyLabel busy2 = new JXBusyLabel();
            busy2.setBusy(true);
            // stop all existing busy labels before we add the new ones...
            stopAllBusyLabels();
            tabs.setComponentAt(3, UtilGUI.getCentredPanel(busy1));
            tabs.setComponentAt(4, UtilGUI.getCentredPanel(busy2));
          }
        });
    // Use a swing worker as construct takes a lot of time
    SwingWorker<Void, Void> sw =
        new SwingWorker<Void, Void>() {
          JScrollPane jsp1;
          JScrollPane jsp2;

          @Override
          public Void doInBackground() {
            try {
              // Fetch last.fm calls and downloads covers
              preFetchOthersAlbum();
              preFetchSimilarArtists();
            } catch (Exception e) {
              Log.error(e);
            }
            return null;
          }

          @Override
          public void done() {
            jsp1 = getLastFMSuggestionsPanel(SuggestionType.OTHERS_ALBUMS, false);
            jsp2 = getLastFMSuggestionsPanel(SuggestionType.SIMILAR_ARTISTS, false);
            stopAllBusyLabels();
            tabs.setComponentAt(3, (jsp1 == null) ? new JPanel() : jsp1);
            tabs.setComponentAt(4, (jsp2 == null) ? new JPanel() : jsp2);
          }
        };
    sw.execute();
  }