/* * Jajuk * Copyright (C) The Jajuk Team * http://jajuk.info * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ package org.jajuk.base; import java.net.MalformedURLException; import java.net.URL; import javax.swing.ImageIcon; import org.jajuk.ui.thumbnails.ThumbnailManager; import org.jajuk.util.Conf; import org.jajuk.util.Const; import org.jajuk.util.IconLoader; import org.jajuk.util.JajukIcons; import org.jajuk.util.Messages; import org.jajuk.util.UtilString; import org.jajuk.util.UtilSystem; import org.jajuk.util.log.Log; /** * A music file to be played * <p> * Physical item. */ public class File extends PhysicalItem implements Comparable<File> { /** Parent directory. */ private final Directory directory; /** Associated track. */ private Track track; /** IO file associated with this file. */ private java.io.File fio; /** * File instantiation. * * @param sId * @param sName * @param directory * @param track * @param lSize * @param lQuality */ File(String sId, String sName, Directory directory, Track track, long lSize, long lQuality) { super(sId, sName); this.directory = directory; setProperty(Const.XML_DIRECTORY, directory.getID()); this.track = track; setProperty(Const.XML_TRACK, track.getID()); setProperty(Const.XML_SIZE, lSize); setProperty(Const.XML_QUALITY, lQuality); } /* * (non-Javadoc) * * @see org.jajuk.base.Item#getIdentifier() */ @Override public final String getXMLTag() { return XML_FILE; } /** * toString method. * * @return the string */ @Override public String toString() { return "File[ID=" + getID() + " Name={{" + getName() + "}} Dir=" + directory + " Size=" + getSize() + " Quality=" + getQuality() + "]"; } /** * String representation as displayed in a search result. * * @return the string */ String toStringSearch() { StringBuilder sb = new StringBuilder(track.getGenre().getName2()).append('/') .append(track.getArtist().getName2()).append('/').append(track.getAlbum().getName2()) .append('/').append(track.getName()).append(" [").append(directory.getName()).append('/') .append(getName()).append(']'); return sb.toString(); } /** * Return true is the specified directory is an ancestor for this file. * * @param directory * * @return true, if checks for ancestor */ public boolean hasAncestor(Directory directory) { Directory dirTested = getDirectory(); while (true) { if (dirTested.equals(directory)) { return true; } else { dirTested = dirTested.getParentDirectory(); if (dirTested == null) { return false; } } } } /** * Gets the size. * * @return the size */ public long getSize() { return getLongValue(Const.XML_SIZE); } /** * Gets the directory. * * @return the directory */ public Directory getDirectory() { return directory; } /** * Gets the device. * * @return associated device */ public Device getDevice() { return directory.getDevice(); } /** * Gets the type. * * @return associated type */ public Type getType() { String extension = UtilSystem.getExtension(this.getName()); if (extension != null) { return TypeManager.getInstance().getTypeByExtension(extension); } return null; } /** * Gets the quality. * * @return the quality */ public long getQuality() { return getLongValue(Const.XML_QUALITY); } /** * Gets the track. * * @return the track */ public Track getTrack() { return track; } /** * Return absolute file path name. * * @return String */ public String getAbsolutePath() { StringBuilder sbOut = new StringBuilder(getDevice().getUrl()) .append(getDirectory().getRelativePath()).append(java.io.File.separatorChar) .append(this.getName()); return sbOut.toString(); } /** * Alphabetical comparator used to display ordered lists of files * <p> * Sort ignoring cases * </p> * . * * @param otherFile * * @return comparison result */ @Override public int compareTo(File otherFile) { int comp; // Begin by comparing file parent directory for performances if (directory.equals(otherFile.getDirectory())) { // If both files are in the same directory, sort by track order int iOrder = (int) getTrack().getOrder(); int iOrderOther = (int) otherFile.getTrack().getOrder(); if (iOrder != iOrderOther) { return iOrder - iOrderOther; } // if same order too, simply compare file names String abs = getName(); String otherAbs = otherFile.getName(); // We must be consistent with equals, see // http://java.sun.com/javase/6/docs/api/java/lang/Comparable.html if (abs.equalsIgnoreCase(otherAbs)) { comp = abs.compareTo(otherAbs); } else { comp = abs.compareToIgnoreCase(otherAbs); } return comp; } else { // Files are in different directories, sort by absolute path // Do not compare simply parent directories to avoid general contact violation about transitivity if (UtilSystem.isUnderWindows()) { comp = this.getAbsolutePath().compareToIgnoreCase(otherFile.getAbsolutePath()); } else { comp = this.getAbsolutePath().compareTo(otherFile.getAbsolutePath()); } return comp; } } /** * Return true if the file can be accessed right now. * * @return true the file can be accessed right now */ public boolean isReady() { return getDirectory().getDevice().isMounted(); } /** * Return true if the file is currently refreshed or synchronized. * * @return true if the file is currently refreshed or synchronized */ public boolean isScanned() { if (getDirectory().getDevice().isRefreshing() || getDirectory().getDevice().isSynchronizing()) { return true; } return false; } /** * Return Io file associated with this file. * * @return the FIO */ public java.io.File getFIO() { if (fio == null) { fio = new java.io.File(getAbsolutePath()); } return fio; } /** * Return whether this item should be hidden with hide option. * * @return whether this item should be hidden with hide option */ public boolean shouldBeHidden() { if (getDirectory().getDevice().isMounted() || !Conf.getBoolean(Const.CONF_OPTIONS_HIDE_UNMOUNTED)) { return false; } return true; } /** * Sets the track. * * @param track The track to set. */ public void setTrack(Track track) { // We remove previous track so it will be cleanup (if it maps no more // files). This allow cleaning old tracks after a change of tags from others // programs than jajuk if (!this.track.equals(track)) { TrackManager.getInstance().removeFile(this); this.track = track; setProperty(Const.XML_TRACK, track.getID()); track.addFile(this); } } /* (non-Javadoc) * @see org.jajuk.base.Item#getTitle() */ @Override public String getTitle() { return Messages.getString("Item_File") + " : " + getName(); } /* * (non-Javadoc) * * @see org.jajuk.base.Item#getHumanValue(java.lang.String) */ @Override public String getHumanValue(String sKey) { if (Const.XML_DIRECTORY.equals(sKey)) { Directory dParent = DirectoryManager.getInstance().getDirectoryByID(getStringValue(sKey)); return dParent.getFio().getAbsolutePath(); } else if (Const.XML_TRACK.equals(sKey)) { return getTrack().getName(); } else if (Const.XML_SIZE.equals(sKey)) { return (Math.round(getSize() / 10485.76) / 100f) + Messages.getString("FilesTreeView.54"); } else if (Const.XML_QUALITY.equals(sKey)) { return getQuality() + Messages.getString("FIFO.13"); } else if (Const.XML_ALBUM.equals(sKey)) { return getTrack().getAlbum().getName2(); } else if (Const.XML_GENRE.equals(sKey)) { return getTrack().getGenre().getName2(); } else if (Const.XML_ARTIST.equals(sKey)) { return getTrack().getArtist().getName2(); } else if (Const.XML_TRACK_LENGTH.equals(sKey)) { return UtilString.formatTimeBySec(getTrack().getDuration()); } else if (Const.XML_TRACK_RATE.equals(sKey)) { return Long.toString(getTrack().getRate()); } else if (Const.XML_DEVICE.equals(sKey)) { return getDirectory().getDevice().getName(); } else if (Const.XML_ANY.equals(sKey)) { return getAny(); } else {// default // check if this key is known if (getMeta(sKey) != null) { return super.getHumanValue(sKey); } // Unknown ? check if it is a track custom property else if (getTrack().getMeta(sKey) != null) { return getTrack().getHumanValue(sKey); } else { return null; } } } /** * Gets the any. * * @return a human representation of all concatenated properties */ @Override public String getAny() { // rebuild any StringBuilder sb = new StringBuilder(100); File file = this; Track lTrack = file.getTrack(); sb.append(super.getAny()); // add all files-based properties // now add others properties sb.append(file.getDirectory().getDevice().getName()); sb.append(lTrack.getName()); sb.append(lTrack.getGenre().getName2()); sb.append(lTrack.getArtist().getName2()); sb.append(lTrack.getAlbum().getName2()); sb.append(lTrack.getDuration()); sb.append(lTrack.getRate()); sb.append(lTrack.getValue(Const.XML_TRACK_COMMENT)); AlbumArtist albumArtist = lTrack.getAlbumArtist(); if (albumArtist != null) { sb.append(albumArtist.getName2()); } return sb.toString(); } /** * Reset pre-calculated paths*. */ protected void reset() { // sAbs = null; fio = null; } /* * (non-Javadoc) * * @see org.jajuk.base.Item#getIconRepresentation() */ @Override public ImageIcon getIconRepresentation() { ImageIcon icon = null; String ext = UtilSystem.getExtension(getName()); // getName() is better // here as // it will do less and not // create java.io.File in File Type type = TypeManager.getInstance().getTypeByExtension(ext); // Find associated icon with this type URL iconUrl = null; String sIcon; if (type != null) { sIcon = (String) type.getValue(Const.XML_TYPE_ICON); try { iconUrl = new URL(sIcon); } catch (MalformedURLException e) { Log.error(e); } } if (iconUrl == null) { icon = IconLoader.getIcon(JajukIcons.TYPE_WAV); } else { icon = new ImageIcon(iconUrl); } return icon; } /** * Set name (useful for Windows because same object can have different cases). * * @param name Item name */ @Override protected void setName(String name) { setProperty(Const.XML_NAME, name); this.name = name; } /** * Gets the html format text. * * @return text to be displayed in the tray balloon and tooltip with HTML * formating that is used correctly under Linux */ public String getHTMLFormatText() { String sOut = ""; sOut += "<HTML>"; int size = 100; int maxSize = 30; ThumbnailManager.refreshThumbnail(getTrack().getAlbum(), size); java.io.File cover = ThumbnailManager.getThumbBySize(getTrack().getAlbum(), size); if (cover.canRead()) { sOut += "<p ALIGN=center><img src='file:" + cover.getAbsolutePath() + "'/></p>"; } sOut += "<b>" + UtilString.getLimitedString(getTrack().getName(), maxSize) + "</b><br/>"; String sArtist = UtilString.getLimitedString(getTrack().getArtist().getName(), maxSize); if (!sArtist.equals(UNKNOWN_ARTIST)) { sOut += sArtist + "<br/>"; } String sAlbum = UtilString.getLimitedString(getTrack().getAlbum().getName(), maxSize); if (!sAlbum.equals(UNKNOWN_ALBUM)) { sOut += sAlbum + "<br/>"; } sOut += "</HTML>"; return sOut; } }