void OSDWidget::ratingChanged( const QString& path, int rating ) { Meta::TrackPtr track = The::engineController()->currentTrack(); if( !track ) return; if( track->playableUrl().isLocalFile() && track->playableUrl().path() == path ) ratingChanged( rating ); }
void Amarok::OSD::show( Meta::TrackPtr track ) //slot { setAlignment( static_cast<OSDWidget::Alignment>( AmarokConfig::osdAlignment() ) ); setOffset( AmarokConfig::osdYOffset() ); QString text; if( !track || track->playableUrl().isEmpty() ) { text = i18n( "No track playing" ); setRating( 0 ); // otherwise stars from last rating change are visible } else { setRating( track->rating() ); text = track->prettyName(); if( track->artist() && !track->artist()->prettyName().isEmpty() ) text = track->artist()->prettyName() + " - " + text; if( track->album() && !track->album()->prettyName().isEmpty() ) text += "\n (" + track->album()->prettyName() + ") "; else text += '\n'; if( track->length() > 0 ) text += Meta::msToPrettyTime( track->length() ); } if( text.isEmpty() ) text = track->playableUrl().fileName(); if( text.startsWith( "- " ) ) //When we only have a title tag, _something_ prepends a f*****g hyphen. Remove that. text = text.mid( 2 ); if( text.isEmpty() ) //still text = i18n("No information available for this track"); QImage image; if( track && track->album() ) image = The::svgHandler()->imageWithBorder( track->album(), 100, 5 ).toImage(); OSDWidget::show( text, image ); }
/** * called whenever metadata of the current track has changed */ void TabsEngine::update() { DEBUG_BLOCK // get the current track Meta::TrackPtr track = The::engineController()->currentTrack(); if( !track ) { debug() << "no track"; m_titleName.clear(); m_artistName.clear(); removeAllData( "tabs" ); setData( "tabs", "state", "Stopped" ); return; } m_currentTrack = track; Meta::ArtistPtr artistPtr = track->artist(); QString newArtist; if( artistPtr ) { if( ( track->playableUrl().protocol() == "lastfm" ) || ( track->playableUrl().protocol() == "daap" ) || !The::engineController()->isStream() ) newArtist = artistPtr->name(); else newArtist = artistPtr->prettyName(); } QString newTitle = track->name(); if( newTitle.isEmpty() ) newTitle = track->prettyName(); // check if something changed if( newTitle == m_titleName && newArtist == m_artistName ) { debug() << "nothing changed"; return; } // stop fetching for unknown artists or titles if( newTitle.isEmpty() || newArtist.isEmpty() ) { setData("tabs", "state", "noTabs" ); return; } requestTab( newArtist, newTitle ); }
QString TrackOrganizer::buildDestination(const QString& format, const Meta::TrackPtr& track) const { // get hold of the shared pointers Meta::AlbumPtr album = track->album(); Meta::ArtistPtr artist = track->artist(); Meta::ComposerPtr composer = track->composer(); Meta::ArtistPtr albumArtist = album ? album->albumArtist() : Meta::ArtistPtr(); Meta::GenrePtr genre = track->genre(); Meta::YearPtr year = track->year(); bool isCompilation = album && album->isCompilation(); QMap<QString, QString> args; QString strArtist = artist ? artist->name() : QString(); QString strAlbumArtist = isCompilation ? i18n( "Various Artists" ) : ( albumArtist ? albumArtist->name() : strArtist ); args["theartist"] = strArtist; args["thealbumartist"] = strAlbumArtist; if( m_postfixThe ) { Amarok::manipulateThe( strArtist, true ); Amarok::manipulateThe( strAlbumArtist, true ); } if ( track->trackNumber() ) { QString trackNum = QString("%1").arg( track->trackNumber(), 2, 10, QChar('0') ); args["track"] = trackNum; } args["title"] = track->name(); args["artist"] = strArtist; args["composer"] = composer ? composer->name() : QString(); // if year == 0 then we don't want include it QString strYear = year ? year->name() : QString(); args["year"] = strYear.localeAwareCompare( "0" ) == 0 ? QString() : strYear; args["album"] = track->album() ? track->album()->name() : QString(); args["albumartist"] = strAlbumArtist; args["comment"] = track->comment(); args["genre"] = genre ? genre->name() : QString(); if( m_targetFileExtension.isEmpty() ) args["filetype"] = track->type(); else args["filetype"] = m_targetFileExtension; QString strFolder = QFileInfo( track->playableUrl().toLocalFile() ).path(); strFolder = strFolder.mid( commonPrefixLength( m_folderPrefix, strFolder ) ); args["folder"] = strFolder; args["initial"] = strAlbumArtist.mid( 0, 1 ).toUpper(); //artists starting with The are already handled above if( track->discNumber() ) args["discnumber"] = QString::number( track->discNumber() ); args["collectionroot"] = m_folderPrefix; // some additional properties not supported by organize dialog. args["rating"] = track->statistics()->rating(); args["filesize"] = track->filesize(); args["length"] = track->length() / 1000; // Fill up default empty values for StringX formater // TODO make this values changeable by user args["default_album"] = i18n( "Unknown album" ); args["default_albumartist"] = i18n( "Unknown artist" ); args["default_artist"] = args["albumartist"]; args["default_thealbumartist"] = args["albumartist"]; args["default_theartist"] = args["albumartist"]; args["default_comment"] = i18n( "No comments" ); args["default_composer"] = i18n( "Unknown composer" ); args["default_discnumber"] = i18n( "Unknown disc number" ); args["default_genre"] = i18n( "Unknown genre" ); args["default_title"] = i18n( "Unknown title" ); args["default_year"] = i18n( "Unknown year" ); foreach( const QString &key, args.keys() ) if( key != "collectionroot" && key != "folder" ) args[key] = args[key].replace( '/', '-' ); Amarok::QStringx formatx( format ); QString result = formatx.namedOptArgs( args ); return cleanPath( result ); }
void WikipediaEngine::update() { DEBUG_BLOCK m_triedRefinedSearch = false; QString tmpWikiStr; unsubscribeFrom( m_currentTrack ); Meta::TrackPtr currentTrack = The::engineController()->currentTrack(); m_currentTrack = currentTrack; subscribeTo( currentTrack ); if ( !currentTrack ) return; DataEngine::Data data; if( selection() == "artist" ) // default, or applet told us to fetch artist { data["wikipedia"] = "label, artist"; if( currentTrack->artist() ) { data["wikipedia"] = "title", currentTrack->artist()->prettyName(); if ( ( currentTrack->playableUrl().protocol() == "lastfm" ) || ( currentTrack->playableUrl().protocol() == "daap" ) || !The::engineController()->isStream() ) { tmpWikiStr = currentTrack->artist()->name(); tmpWikiStr += wikiArtistPostfix(); //makes wikipedia bail out debug() << "tmpWikiStr: " << tmpWikiStr; } else { tmpWikiStr = currentTrack->artist()->prettyName(); tmpWikiStr += wikiArtistPostfix(); //makes wikipedia bail out } } } else if( selection() == "title" ) { tmpWikiStr = currentTrack->prettyName(); data["wikipedia"] = QString( "label" ), QString( "Title" ); data["wikipedia"] = "title", currentTrack->prettyName(); } else if( selection() == "album" ) { if( currentTrack->album() ) { data["wikipedia"] = QString( "label" ), QString( "Album" ); data["wikipedia"] = "title", currentTrack->album()->prettyName(); if ( ( currentTrack->playableUrl().protocol() == "lastfm" ) || ( currentTrack->playableUrl().protocol() == "daap" ) || !The::engineController()->isStream() ) { tmpWikiStr = currentTrack->album()->name(); tmpWikiStr += wikiAlbumPostfix(); } } } //Hack to make wiki searches work with magnatune preview tracks if ( tmpWikiStr.contains( "PREVIEW: buy it at www.magnatune.com" ) ) { tmpWikiStr = tmpWikiStr.remove(" (PREVIEW: buy it at www.magnatune.com)" ); int index = tmpWikiStr.indexOf( '-' ); if ( index != -1 ) tmpWikiStr = tmpWikiStr.left (index - 1); } if( m_wikiCurrentEntry == tmpWikiStr ) { debug() << "Same entry requested again. Ignoring."; return; } removeAllData( "wikipedia" ); foreach( const QString &key, data.keys() ) setData( key, data[key] ); m_wikiCurrentEntry = tmpWikiStr; m_wikiCurrentUrl = wikiUrl( tmpWikiStr ); debug() << "wiki url: " << m_wikiCurrentUrl; setData( "wikipedia", "message", i18n( "Fetching content.." ) ); m_wikiJob = KIO::storedGet( m_wikiCurrentUrl, KIO::NoReload, KIO::HideProgressInfo ); connect( m_wikiJob, SIGNAL( result( KJob* ) ), SLOT( wikiResult( KJob* ) ) ); }
bool MoodbarManager::hasMoodbar( Meta::TrackPtr track ) { //check if we already checked this track: if ( m_hasMoodMap.contains( track ) ) { //debug() << "Cached value, returning: " << m_hasMoodMap.value( track ); return m_hasMoodMap.value( track ); } KUrl trackUrl = track->playableUrl(); //only supports local files for now. if ( !trackUrl.isLocalFile() ) { debug() << "non local file, no moodbar..."; m_hasMoodMap.insert( track, false ); return false; } //do we already have a moodFile path for this track? QString moodFilePath; if ( m_moodFileMap.contains( track ) ) moodFilePath = m_moodFileMap.value( track ); else { //Now, lets see if there is a mood file that matches the track filename moodFilePath = moodPath( trackUrl.path() ); } debug() << "file path: " << trackUrl.path(); debug() << "mood file path: " << moodFilePath; if( !QFile::exists( moodFilePath ) ) { debug() << "no such file"; //for fun, try without the leading '.' QFileInfo fInfo( moodFilePath ); QString testName = fInfo.fileName(); testName.remove( 0, 1 ); moodFilePath.replace( fInfo.fileName(), testName ); debug() << "trying : " << moodFilePath; if( !QFile::exists( moodFilePath ) ) { debug() << "no luck removing the leading '.' either..."; m_hasMoodMap.insert( track, false ); return false; } debug() << "whoops, missing leading '.', so mood file path: " << moodFilePath; } //it is a local file with a matching .mood file. Good enough for now! m_moodFileMap.insert( track, moodFilePath ); m_hasMoodMap.insert( track, true ); return true; }
QPixmap MoodbarManager::getMoodbar( Meta::TrackPtr track, int width, int height, bool rtl ) { //if we have already marked this track as //not having a moodbar, don't even bother... if ( m_hasMoodMap.contains( track ) ) if( !m_hasMoodMap.value( track ) ) return QPixmap(); //first of all... Check if rendering settings have changed. If //so, clear data and pixmap caches. if( m_lastPaintMode != AmarokConfig::moodbarPaintStyle() ) { m_lastPaintMode = AmarokConfig::moodbarPaintStyle(); m_cache->clear(); m_moodDataMap.clear(); emit moodbarStyleChanged(); } //Do we already have this pixmap cached? const QString pixmapKey = QString( "mood:%1-%2x%3%4" ).arg( track->uidUrl() ).arg(width).arg(height).arg( rtl?"r":"" ); QPixmap moodbar; if( m_cache->findPixmap( pixmapKey, &moodbar ) ) return moodbar; //No? Ok, then create it reusing as much info as possible MoodbarColorList data; if ( m_moodDataMap.contains( track ) ) data = m_moodDataMap.value( track ); else { QString moodFilePath; if ( m_moodFileMap.contains( track ) ) moodFilePath = m_moodFileMap.value( track ); else moodFilePath = moodPath( track->playableUrl().path() ); data = readMoodFile( moodFilePath ); if ( data.size() > 10 ) m_moodDataMap.insert( track, data ); else { //likely a corrupt file, so mark this track as not having a moodbar m_hasMoodMap.insert( track, false ); } } //assume that the readMoodFile function emits the proper error... if ( data.size() < 10 ) return moodbar; moodbar = drawMoodbar( data, width, height, rtl ); m_cache->insertPixmap( pixmapKey, moodbar ); return moodbar; }
void ITunesImporterWorker::readTrackElement() { QString title, artist, album, url; int year = -1, bpm = -1, playcount = -1, rating = -1; QDateTime lastplayed; while( !( isEndElement() && name() == "dict" ) ) { readNext(); QString text = readElementText(); if( name() == "key" && text == "Name" ) { readNext(); // skip past the </key> and to the data tag QString text = readElementText(); title = text; } else if( name() == "key" && text == "Artist" ) { readNext(); // skip past the </key> and to the data tag artist = readElementText(); } else if( isStartElement() && name() == "key" && text == "Album" ) { readNext(); // skip past the </key> and to the data tag album = readElementText(); } else if( name() == "key" && text == "Year" ) { readNext(); // skip past the </key> and to the data tag year = readElementText().toInt(); } else if( name() == "key" && text == "BPM" ) { readNext(); // skip past the </key> and to the data tag bpm = readElementText().toInt(); } else if( name() == "key" && text == "Play Count" ) { readNext(); // skip past the </key> and to the data tag playcount = readElementText().toInt(); } else if( name() == "key" && text == "Rating" ) { readNext(); // skip past the </key> and to the data tag rating = readElementText().toInt() / 10; // itunes rates 0-100 } else if( name() == "key" && text == "Play Date" ) { readNext(); // skip past the </key> and to the data tag lastplayed = QDateTime::fromTime_t(readElementText().toInt()); } else if( name() == "key" && text == "Location" ) { readNext(); // skip past the </key> and to the data tag url = readElementText(); } } //split the file://localhost/path/to/track to just file:///path/to/track if( url.indexOf( "file://localhost" ) == 0 ) url = url.remove( 7, 9 ); debug() << "got track info:" << title << artist << album << year << bpm << url; Meta::TrackPtr track = CollectionManager::instance()->trackForUrl( KUrl( url ) ); if( track ) { QScopedPointer<Capabilities::StatisticsCapability> ec( track->create<Capabilities::StatisticsCapability>() ); if( ec ) { ec->beginStatisticsUpdate(); if( rating != -1 ) ec->setRating( rating ); if( lastplayed.isValid() ) ec->setLastPlayed( lastplayed ); if( playcount != -1 ) ec->setPlayCount( playcount ); ec->endStatisticsUpdate(); if( !track->inCollection() ) { m_tracksForInsert.insert( track, track->playableUrl().url() ); debug() << " inserting track:" << track->playableUrl(); } else { Collections::Collection* collection = track->collection(); if (collection) debug() << "track in collection (" << collection->location()->prettyLocation() << "):" << track->playableUrl(); } emit trackAdded( track ); } } }
App::~App() { DEBUG_BLOCK CollectionManager::instance()->stopScan(); // Hiding the OSD before exit prevents crash Amarok::OSD::instance()->hide(); // This following can't go in the PlaylistModel destructor, because by the time that // happens, the Config has already been written. // Use the bottom model because that provides the most dependable/invariable row // number to save in an external file. AmarokConfig::setLastPlaying( Playlist::ModelStack::instance()->bottom()->activeRow() ); if ( AmarokConfig::resumePlayback() ) { Meta::TrackPtr engineTrack = The::engineController()->currentTrack(); if( engineTrack ) { AmarokConfig::setResumeTrack( engineTrack->playableUrl().prettyUrl() ); AmarokConfig::setResumeTime( The::engineController()->trackPositionMs() ); } else AmarokConfig::setResumeTrack( QString() ); //otherwise it'll play previous resume next time! } The::engineController()->endSession(); //records final statistics #ifndef Q_WS_MAC // do even if trayicon is not shown, it is safe Amarok::config().writeEntry( "HiddenOnExit", mainWindow()->isHidden() ); AmarokConfig::self()->writeConfig(); #else // for some reason on OS X the main window always reports being hidden // this means if you have the tray icon enabled, amarok will always open minimized Amarok::config().writeEntry( "HiddenOnExit", false ); AmarokConfig::self()->writeConfig(); #endif ScriptManager::destroy(); // this must be deleted before the connection to the Xserver is // severed, or we risk a crash when the QApplication is exited, // I asked Trolltech! *smug* Amarok::OSD::destroy(); Amarok::KNotificationBackend::destroy(); AmarokConfig::self()->writeConfig(); //mainWindow()->deleteBrowsers(); delete mainWindow(); Playlist::Controller::destroy(); Playlist::ModelStack::destroy(); Playlist::Actions::destroy(); PlaylistManager::destroy(); CoverFetcher::destroy(); CoverCache::destroy(); CollectionManager::destroy(); NetworkAccessManagerProxy::destroy(); Plugins::PluginManager::destroy(); //this should be moved to App::quit() I guess Amarok::Components::applicationController()->shutdown(); #ifdef Q_WS_WIN // work around for KUniqueApplication being not completely implemented on windows QDBusConnectionInterface* dbusService; if (QDBusConnection::sessionBus().isConnected() && (dbusService = QDBusConnection::sessionBus().interface())) { dbusService->unregisterService("org.mpris.amarok"); dbusService->unregisterService("org.mpris.MediaPlayer2.amarok"); } #endif }
virtual QString value( Meta::TrackPtr track ) const { return track->playableUrl().url(); }
QVariant Meta::valueForField( qint64 field, Meta::TrackPtr track ) { if( !track ) return QVariant(); switch( field ) { case 0: { // that is the simple search for MetaQueryWidget QSet<QString> allInfos; allInfos += track->playableUrl().path() += track->name() += track->comment(); if( track->artist() ) allInfos += track->artist()->name(); if( track->album() ) allInfos += track->album()->name(); if( track->genre() ) allInfos += track->genre()->name(); return QVariant( allInfos.toList() ); } case Meta::valUrl: return track->playableUrl().path(); case Meta::valTitle: return track->name(); case Meta::valArtist: return track->artist() ? QVariant(track->artist()->name()) : QVariant(); case Meta::valAlbum: return track->album() ? QVariant(track->album()->name()) : QVariant(); case Meta::valGenre: return track->genre() ? QVariant(track->genre()->name()) : QVariant(); case Meta::valComposer: return track->composer() ? QVariant(track->composer()->name()) : QVariant(); case Meta::valYear: return track->year() ? QVariant(track->year()->name().toInt()) : QVariant(); case Meta::valComment: return track->comment(); case Meta::valTrackNr: return track->trackNumber(); case Meta::valDiscNr: return track->discNumber(); case Meta::valBpm: return track->bpm(); case Meta::valLength: return track->length(); case Meta::valBitrate: return track->bitrate(); case Meta::valSamplerate: return track->sampleRate(); case Meta::valFilesize: return track->filesize(); case Meta::valFormat: return int(Amarok::FileTypeSupport::fileType(track->type())); case Meta::valCreateDate: return track->createDate(); case Meta::valScore: return track->statistics()->score(); case Meta::valRating: return track->statistics()->rating(); case Meta::valFirstPlayed: return track->statistics()->firstPlayed(); case Meta::valLastPlayed: return track->statistics()->lastPlayed(); case Meta::valPlaycount: return track->statistics()->playCount(); case Meta::valUniqueId: return track->uidUrl(); // todo case Meta::valTrackGain: return "track gain"; case Meta::valTrackGainPeak: return "track gain peak"; case Meta::valAlbumGain: return "album gain"; case Meta::valAlbumGainPeak: return "album gain peak"; case Meta::valAlbumArtist: return (track->album() && track->album()->albumArtist()) ? QVariant(track->album()->albumArtist()->name()) : QVariant(); case Meta::valLabel: { Meta::LabelList labels = track->labels(); QStringList strLabels; foreach( Meta::LabelPtr label, labels ) strLabels.append( label->name() ); return QVariant( strLabels ); } case Meta::valModified: return track->modifyDate(); default: return QVariant(); } }