Warning, file /multimedia/amarok/src/dialogs/TrackOrganizer.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /*************************************************************************** 0002 * Copyright (c) 2010 Casey Link <unnamedrambler@gmail.com> * 0003 * Copyright (c) 2008 Bonne Eggleston <b.eggleston@gmail.com> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 0019 ***************************************************************************/ 0020 0021 #include "TrackOrganizer.h" 0022 0023 #include "QStringx.h" 0024 #include "core/meta/Meta.h" 0025 #include "core/meta/Statistics.h" 0026 #include "core/support/Amarok.h" 0027 0028 #include <KLocalizedString> 0029 0030 TrackOrganizer::TrackOrganizer( const Meta::TrackList &tracks, QObject* parent ) 0031 : QObject( parent ) 0032 , m_allTracks( tracks ) 0033 , m_trackOffset( 0 ) 0034 , m_postfixThe( false ) 0035 , m_AsciiOnly( false ) 0036 , m_UnderscoresNotSpaces( false ) 0037 , m_vfatSafe( false ) 0038 { 0039 0040 } 0041 0042 QString TrackOrganizer::buildDestination(const QString& format, const Meta::TrackPtr& track) const 0043 { 0044 // get hold of the shared pointers 0045 Meta::AlbumPtr album = track->album(); 0046 Meta::ArtistPtr artist = track->artist(); 0047 Meta::ComposerPtr composer = track->composer(); 0048 Meta::ArtistPtr albumArtist = album ? album->albumArtist() : Meta::ArtistPtr(); 0049 Meta::GenrePtr genre = track->genre(); 0050 Meta::YearPtr year = track->year(); 0051 0052 bool isCompilation = album && album->isCompilation(); 0053 0054 QMap<QString, QString> args; 0055 QString strArtist = artist ? artist->name() : QString(); 0056 QString strAlbumArtist = isCompilation ? i18n( "Various Artists" ) : 0057 ( albumArtist ? albumArtist->name() : strArtist ); 0058 0059 args["theartist"] = strArtist; 0060 args["thealbumartist"] = strAlbumArtist; 0061 0062 if( m_postfixThe ) 0063 { 0064 Amarok::manipulateThe( strArtist, true ); 0065 Amarok::manipulateThe( strAlbumArtist, true ); 0066 } 0067 0068 if ( track->trackNumber() ) 0069 { 0070 QString trackNum = QStringLiteral("%1").arg( track->trackNumber(), 2, 10, QChar('0') ); 0071 args["track"] = trackNum; 0072 } 0073 args["title"] = track->name(); 0074 args["artist"] = strArtist; 0075 args["composer"] = composer ? composer->name() : QString(); 0076 // if year == 0 then we don't want include it 0077 QString strYear = year ? year->name() : QString(); 0078 args["year"] = strYear.localeAwareCompare( "0" ) == 0 ? QString() : strYear; 0079 args["album"] = track->album() ? track->album()->name() : QString(); 0080 args["albumartist"] = strAlbumArtist; 0081 args["comment"] = track->comment(); 0082 args["genre"] = genre ? genre->name() : QString(); 0083 if( m_targetFileExtension.isEmpty() ) 0084 args["filetype"] = track->type(); 0085 else 0086 args["filetype"] = m_targetFileExtension; 0087 QString strFolder = QFileInfo( track->playableUrl().toLocalFile() ).path(); 0088 strFolder = strFolder.mid( commonPrefixLength( m_folderPrefix, strFolder ) ); 0089 args["folder"] = strFolder; 0090 args["initial"] = strAlbumArtist.mid( 0, 1 ).toUpper(); //artists starting with The are already handled above 0091 if( track->discNumber() ) 0092 args["discnumber"] = QString::number( track->discNumber() ); 0093 args["collectionroot"] = m_folderPrefix; 0094 0095 // some additional properties not supported by organize dialog. 0096 args["rating"] = track->statistics()->rating(); 0097 args["filesize"] = track->filesize(); 0098 args["length"] = track->length() / 1000; 0099 0100 // Fill up default empty values for StringX formatter 0101 // TODO make this values changeable by user 0102 args["default_album"] = i18n( "Unknown album" ); 0103 args["default_albumartist"] = i18n( "Unknown artist" ); 0104 args["default_artist"] = args["albumartist"]; 0105 args["default_thealbumartist"] = args["albumartist"]; 0106 args["default_theartist"] = args["albumartist"]; 0107 args["default_comment"] = i18n( "No comments" ); 0108 args["default_composer"] = i18n( "Unknown composer" ); 0109 args["default_discnumber"] = i18n( "Unknown disc number" ); 0110 args["default_genre"] = i18n( "Unknown genre" ); 0111 args["default_title"] = i18n( "Unknown title" ); 0112 args["default_year"] = i18n( "Unknown year" ); 0113 0114 foreach( const QString &key, args.keys() ) 0115 if( key != "collectionroot" && key != "folder" ) 0116 args[key] = args[key].replace( QLatin1Char('/'), '-' ); 0117 0118 Amarok::QStringx formatx( format ); 0119 QString result = formatx.namedOptArgs( args ); 0120 return cleanPath( result ); 0121 } 0122 0123 QString TrackOrganizer::cleanPath( const QString& path ) const 0124 { 0125 QString result = path; 0126 0127 if( m_AsciiOnly ) 0128 { 0129 result = Amarok::cleanPath( result ); 0130 result = Amarok::asciiPath( result ); 0131 } 0132 0133 if( !m_regexPattern.isEmpty() ) 0134 result.replace( QRegExp( m_regexPattern ), m_replaceString ); 0135 0136 result = result.simplified(); 0137 if( m_UnderscoresNotSpaces ) 0138 result.replace( QRegExp( "\\s" ), "_" ); 0139 0140 if( m_vfatSafe ) 0141 // we use UnixBehaviour even on windows, because even there we use / as directory 0142 // separator currently (QFile mangles it internally) 0143 result = Amarok::vfatPath( result, Amarok::UnixBehaviour ); 0144 0145 QFileInfo info( result ); // Used to polish path string. (e.g. remove '//') 0146 return info.absoluteFilePath(); 0147 } 0148 0149 int TrackOrganizer::commonPrefixLength( const QString &a, const QString &b ) 0150 { 0151 int prefix = 0; 0152 while( prefix < a.length() && prefix < b.length() && 0153 a.at(prefix) == b.at(prefix) ) 0154 prefix++; 0155 return prefix; 0156 } 0157 0158 QMap< Meta::TrackPtr, QString > TrackOrganizer::getDestinations( unsigned int batchSize ) 0159 { 0160 QMap<Meta::TrackPtr, QString> destinations; 0161 0162 int newOffset = m_trackOffset + batchSize; 0163 //don't go out of bounds in the for loop 0164 if( newOffset >= m_allTracks.count() ) 0165 newOffset = m_allTracks.count(); 0166 0167 if( batchSize == 0 ) 0168 { 0169 m_trackOffset = 0; 0170 newOffset = m_allTracks.count(); 0171 } 0172 0173 for( ; m_trackOffset < newOffset ; m_trackOffset++ ) 0174 { 0175 Meta::TrackPtr track = m_allTracks.value( m_trackOffset ); 0176 if( track ) 0177 destinations.insert( track, buildDestination( m_format, track ) ); 0178 } 0179 0180 return destinations; 0181 } 0182 0183 void TrackOrganizer::setFormatString( const QString& format ) 0184 { 0185 m_format = format; 0186 } 0187 0188 void TrackOrganizer::setFolderPrefix(const QString& prefix) 0189 { 0190 m_folderPrefix = prefix; 0191 } 0192 0193 void TrackOrganizer::setAsciiOnly(bool flag) 0194 { 0195 m_AsciiOnly = flag; 0196 } 0197 0198 void TrackOrganizer::setPostfixThe(bool flag) 0199 { 0200 m_postfixThe = flag; 0201 } 0202 0203 void TrackOrganizer::setReplaceSpaces(bool flag) 0204 { 0205 m_UnderscoresNotSpaces = flag; 0206 } 0207 0208 void TrackOrganizer::setVfatSafe(bool flag) 0209 { 0210 m_vfatSafe = flag; 0211 } 0212 0213 void TrackOrganizer::setReplace(const QString& regex, const QString& string) 0214 { 0215 m_regexPattern = regex; 0216 m_replaceString = string; 0217 } 0218 0219 void TrackOrganizer::setTargetFileExtension( const QString &fileExtension ) 0220 { 0221 m_targetFileExtension = fileExtension; 0222 }