/* * Cantata * * Copyright (c) 2011-2013 Craig Drummond * */ /* * Copyright (c) 2008 Sander Knopper (sander AT knopper DOT tk) and * Roeland Douma (roeland AT rullzer DOT com) * * This file is part of QtMPC. * * QtMPC 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 * (at your option) any later version. * * QtMPC 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 QtMPC. If not, see . */ #include #include "config.h" #include "song.h" #include "mpdparseutils.h" #include "musiclibraryitemalbum.h" #include "localize.h" #include #include #include const QString Song::constCddaProtocol("cdda:/"); // When displaying albums, we use the 1st track's year as the year of the album. // The map below stores the mapping from artist+album to year. // This way the grouped view can find this quickly... static QMap albumYears; void Song::storeAlbumYear(const Song &s) { albumYears.insert(s.albumKey(), s.year); } int Song::albumYear(const Song &s) { QMap::ConstIterator it=albumYears.find(s.albumKey()); return it==albumYears.end() ? s.year : it.value(); } static bool useComposerIfSet=false; bool Song::useComposer() { return useComposerIfSet; } void Song::setUseComposer(bool u) { useComposerIfSet=u; } const quint16 Song::constNullKey(0xFFFF); Song::Song() : id(-1) // , pos(0) , disc(0) , priority(0) , time(0) , track(0) , year(0) , type(Standard) , guessed(false) , size(0) , key(constNullKey) { } Song & Song::operator=(const Song &s) { id = s.id; file = s.file; time = s.time; album = s.album; artist = s.artist; albumartist = s.albumartist; composer = s.composer; title = s.title; track = s.track; // pos = s.pos; disc = s.disc; priority = s.priority; year = s.year; genre = s.genre; name = s.name; size = s.size; key = s.key; type = s.type; guessed = s.guessed; return *this; } bool Song::operator==(const Song &o) const { return 0==compareTo(o); } bool Song::operator<(const Song &o) const { return compareTo(o)<0; } int Song::compareTo(const Song &o) const { if (type!=o.type) { return type keys; if (isStream() && !isCantataStream()) { key=0; return; } QString songKey(albumKey()); QMap::ConstIterator it=keys.find(songKey); if (it!=keys.end()) { key=it.value(); } else { currentKey++; // Key 0 is for streams, so we need to increment before setting... keys.insert(songKey, currentKey); key=currentKey; } } bool Song::isUnknown() const { QString unknown=i18n("Unknown"); return (artist.isEmpty() || artist==unknown) && (album.isEmpty() || album==unknown) && (title.isEmpty() || title==unknown); } void Song::clear() { id = -1; file.clear(); time = 0; album.clear(); artist.clear(); title.clear(); track = 0; // pos = 0; disc = 0; year = 0; genre.clear(); name.clear(); size = 0; type = Standard; } QString Song::formattedTime(quint32 seconds, bool zeroIsUnknown) { if (0==seconds && zeroIsUnknown) { return i18n("Unknown"); } static const quint32 constHour=60*60; if (seconds>constHour) { return MPDParseUtils::formatDuration(seconds); } QString result(QString::number(floor(seconds / 60.0))+QChar(':')); if (seconds % 60 < 10) { result += "0"; } return result+QString::number(seconds % 60); } /* * Genarate a string with song info. * Currently in this format: * artist - [album -][#.] song */ QString Song::format() { QString s = artist + " - "; if (!album.isEmpty()) { s += album + " - "; } if (track != 0) { s += QString::number(track) + ". "; } s += title; return s; } QString Song::entryName() const { if (title.isEmpty()) { return file; } return i18nc("Song\nArtist\nAlbum", "%1\n%2\n%3", title, artist, album); } QString Song::artistOrComposer() const { return useComposerIfSet && !composer.isEmpty() ? composer : albumArtist(); } QString Song::albumName() const { return useComposerIfSet && !composer.isEmpty() && composer!=albumArtist() ? album+QLatin1String(" (")+albumArtist()+QLatin1Char(')') : album; } QString Song::artistSong() const { return artist+QLatin1String(" - ")+title; } QString Song::trackAndTitleStr(bool addArtist) const { return (track>9 ? QString::number(track) : (QChar('0')+QString::number(track))) +QChar(' ')+(addArtist ? artistSong() : title); } void Song::updateSize(const QString &dir) const { if (size<=0) { size=QFileInfo(dir+file).size(); } } bool Song::isVariousArtists(const QString &str) { return QLatin1String("Various Artists")==str || i18n("Various Artists")==str; } bool Song::fixVariousArtists() { if (isVariousArtists()) { artist.replace(" - ", ", "); title=artistSong(); artist=albumartist; return true; } return false; } bool Song::revertVariousArtists() { if (artist==albumartist) { // Then real artist is embedded in track title... int sepPos=title.indexOf(QLatin1String(" - ")); if (sepPos>0 && sepPos