metabundle.cpp

来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 1,884 行 · 第 1/5 页

CPP
1,884
字号
// Max Howell <max.howell@methylblue.com>, (C) 2004// Alexandre Pereira de Oliveira <aleprj@gmail.com>, (C) 2005, 2006// Gábor Lehel <illissius@gmail.com>, (C) 2005, 2006// Shane King <kde@dontletsstart.com>, (C) 2006// Peter C. Ndikuwera <pndiku@gmail.com>, (C) 2006// License: GNU General Public License V2#define DEBUG_PREFIX "MetaBundle"#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include <time.h>#include <sys/time.h>#include <sys/types.h>#include <fcntl.h>#include "amarok.h"#include "amarokconfig.h"#include "debug.h"#include "collectiondb.h"#include "metabundlesaver.h"#include <kapplication.h>#include <kfilemetainfo.h>#include <kio/global.h>#include <kio/job.h>#include <kio/jobclasses.h>#include <kio/netaccess.h>#include <kmdcodec.h>#include <qdeepcopy.h>#include <qfile.h> //decodePath()#include <taglib/attachedpictureframe.h>#include <taglib/fileref.h>#include <taglib/id3v1genres.h> //used to load genre list#include <taglib/mpegfile.h>#include <taglib/tag.h>#include <taglib/tstring.h>#include <taglib/tlist.h>#include <taglib/apetag.h>#include <taglib/id3v2tag.h>#include <taglib/id3v1tag.h>#include <taglib/mpcfile.h>#include <taglib/mpegfile.h>#include <taglib/oggfile.h>#include <taglib/oggflacfile.h>#include <taglib/vorbisfile.h>#include <taglib/flacfile.h>#include <taglib/textidentificationframe.h>#include <taglib/uniquefileidentifierframe.h>#include <taglib/xiphcomment.h>#include <config.h>#ifdef HAVE_MP4V2#include "metadata/mp4/mp4file.h"#include "metadata/mp4/mp4tag.h"#else#include "metadata/m4a/mp4file.h"#include "metadata/m4a/mp4itunestag.h"#endif#include "lastfm.h"#include "metabundle.h"#include "podcastbundle.h"namespace Amarok {    KURL detachedKURL( const KURL &url ) {        KURL urlCopy;        if (!url.isEmpty())            urlCopy = KURL(url.url());        return urlCopy;    }}MetaBundle::EmbeddedImage::EmbeddedImage( const TagLib::ByteVector& data, const TagLib::String& description )    : m_description( TStringToQString( description ) ){    m_data.duplicate( data.data(), data.size() );}const QCString &MetaBundle::EmbeddedImage::hash() const{    if( m_hash.isEmpty() ) {        m_hash = KMD5( m_data ).hexDigest();    }    return m_hash;}bool MetaBundle::EmbeddedImage::save( const QDir& dir ) const{    QFile   file( dir.filePath( hash() ) );    if( file.open( IO_WriteOnly | IO_Raw ) ) {        const Q_LONG s = file.writeBlock( m_data.data(), m_data.size() );        if( s >= 0 && Q_ULONG( s ) == m_data.size() ) {            debug() << "EmbeddedImage::save " << file.name() << endl;            return true;        }        file.remove();    }    debug() << "EmbeddedImage::save failed! " << file.name() << endl;    return false;}/// These are untranslated and used for storing/retrieving XML playlistconst QString &MetaBundle::exactColumnName( int c ) //static{    // construct static qstrings to avoid constructing them all the time    static QString columns[] = {        "Filename", "Title", "Artist", "AlbumArtist", "Composer", "Year", "Album", "DiscNumber", "Track", "BPM", "Genre", "Comment",        "Directory", "Type", "Length", "Bitrate", "SampleRate", "Score", "Rating", "PlayCount", "LastPlayed",        "Mood", "Filesize" };    static QString error( "ERROR" );    if ( c >= 0 && c < NUM_COLUMNS )        return columns[c];    else        return error;}const QString MetaBundle::prettyColumnName( int index ) //static{    switch( index )    {        case Filename:   return i18n( "Filename"    );        case Title:      return i18n( "Title"       );        case Artist:     return i18n( "Artist"      );        case AlbumArtist:return i18n( "Album Artist");        case Composer:   return i18n( "Composer"    );        case Year:       return i18n( "Year"        );        case Album:      return i18n( "Album"       );        case DiscNumber: return i18n( "Disc Number" );        case Track:      return i18n( "Track"       );        case Bpm:        return i18n( "BPM"         );        case Genre:      return i18n( "Genre"       );        case Comment:    return i18n( "Comment"     );        case Directory:  return i18n( "Directory"   );        case Type:       return i18n( "Type"        );        case Length:     return i18n( "Length"      );        case Bitrate:    return i18n( "Bitrate"     );        case SampleRate: return i18n( "Sample Rate" );        case Score:      return i18n( "Score"       );        case Rating:     return i18n( "Rating"      );        case PlayCount:  return i18n( "Play Count"  );        case LastPlayed: return i18n( "Column name", "Last Played" );        case Mood:       return i18n( "Mood"        );        case Filesize:   return i18n( "File Size"   );    }    return "This is a bug.";}int MetaBundle::columnIndex( const QString &name ){    for( int i = 0; i < NUM_COLUMNS; ++i )        if( exactColumnName( i ).lower() == name.lower() )            return i;    return -1;}MetaBundle::MetaBundle()        : m_uniqueId( QString::null )        , m_year( Undetermined )        , m_discNumber( Undetermined )        , m_track( Undetermined )        , m_bpm( Undetermined )        , m_bitrate( Undetermined )        , m_length( Undetermined )        , m_sampleRate( Undetermined )        , m_score( Undetermined )        , m_rating( Undetermined )        , m_playCount( Undetermined )        , m_lastPlay( abs( Undetermined ) )        , m_filesize( Undetermined )        , m_moodbar( 0 )        , m_type( other )        , m_exists( true )        , m_isValidMedia( true )        , m_isCompilation( false )        , m_notCompilation( false )        , m_safeToSave( false )        , m_waitingOnKIO( 0 )        , m_tempSavePath( QString::null )        , m_origRenamedSavePath( QString::null )        , m_tempSaveDigest( 0 )        , m_saveFileref( 0 )        , m_podcastBundle( 0 )        , m_lastFmBundle( 0 )        , m_isSearchDirty(true)        , m_searchColumns( Undetermined ){    init();}MetaBundle::MetaBundle( const KURL &url, bool noCache, TagLib::AudioProperties::ReadStyle readStyle, EmbeddedImageList* images )    : m_url( url )    , m_uniqueId( QString::null )    , m_year( Undetermined )    , m_discNumber( Undetermined )    , m_track( Undetermined )    , m_bpm( Undetermined )    , m_bitrate( Undetermined )    , m_length( Undetermined )    , m_sampleRate( Undetermined )    , m_score( Undetermined )    , m_rating( Undetermined )    , m_playCount( Undetermined )    , m_lastPlay( abs( Undetermined ) )    , m_filesize( Undetermined )    , m_moodbar( 0 )    , m_type( other )    , m_exists( isFile() && QFile::exists( url.path() ) )    , m_isValidMedia( false )    , m_isCompilation( false )    , m_notCompilation( false )    , m_safeToSave( false )    , m_waitingOnKIO( 0 )    , m_tempSavePath( QString::null )    , m_origRenamedSavePath( QString::null )    , m_tempSaveDigest( 0 )    , m_saveFileref( 0 )    , m_podcastBundle( 0 )    , m_lastFmBundle( 0 )    , m_isSearchDirty(true)    , m_searchColumns( Undetermined ){    if ( exists() )    {        if ( !noCache )            m_isValidMedia = CollectionDB::instance()->bundleForUrl( this );        if ( !isValidMedia() || ( !m_podcastBundle && m_length <= 0 ) )            readTags( readStyle, images );    }    else    {        // if it's a podcast we might get some info this way        CollectionDB::instance()->bundleForUrl( this );        m_bitrate = m_length = m_sampleRate = Unavailable;    }}//StreamProvider ctorMetaBundle::MetaBundle( const QString& title,                        const QString& streamUrl,                        const int      bitrate,                        const QString& genre,                        const QString& streamName,                        const KURL& url )        : m_url       ( url )        , m_genre     ( genre )        , m_streamName( streamName )        , m_streamUrl ( streamUrl )        , m_uniqueId( QString::null )        , m_year( 0 )        , m_discNumber( 0 )        , m_track( 0 )        , m_bpm( Undetermined )        , m_bitrate( bitrate )        , m_length( Irrelevant )        , m_sampleRate( Unavailable )        , m_score( Undetermined )        , m_rating( Undetermined )        , m_playCount( Undetermined )        , m_lastPlay( abs( Undetermined ) )        , m_filesize( Undetermined )        , m_moodbar( 0 )        , m_type( other )        , m_exists( true )        , m_isValidMedia( false )        , m_isCompilation( false )        , m_notCompilation( false )        , m_safeToSave( false )        , m_waitingOnKIO( 0 )        , m_tempSavePath( QString::null )        , m_origRenamedSavePath( QString::null )        , m_tempSaveDigest( 0 )        , m_saveFileref( 0 )        , m_podcastBundle( 0 )        , m_lastFmBundle( 0 )        , m_isSearchDirty( true )        , m_searchColumns( Undetermined ){    if( title.contains( '-' ) )    {        m_title  = title.section( '-', 1, 1 ).stripWhiteSpace();        m_artist = title.section( '-', 0, 0 ).stripWhiteSpace();    }    else    {        m_title  = title;        m_artist = streamName; //which is sort of correct..    }}MetaBundle::MetaBundle( const MetaBundle &bundle )        : m_moodbar( 0 ){    *this = bundle;}MetaBundle::~MetaBundle(){    delete m_podcastBundle;    delete m_lastFmBundle;    if( m_moodbar != 0 )      delete m_moodbar;}MetaBundle&MetaBundle::operator=( const MetaBundle& bundle ){    m_url = bundle.m_url;    m_title = bundle.m_title;    m_artist = bundle.m_artist;    m_albumArtist = bundle.m_albumArtist;    m_composer = bundle.m_composer;    m_album = bundle.m_album;    m_comment = bundle.m_comment;    m_genre = bundle.m_genre;    m_streamName = bundle.m_streamName;    m_streamUrl = bundle.m_streamUrl;    m_uniqueId = bundle.m_uniqueId;    m_year = bundle.m_year;    m_discNumber = bundle.m_discNumber;    m_track = bundle.m_track;    m_bpm = bundle.m_bpm;    m_bitrate = bundle.m_bitrate;    m_length = bundle.m_length;    m_sampleRate = bundle.m_sampleRate;    m_score = bundle.m_score;    m_rating = bundle.m_rating;    m_playCount = bundle.m_playCount;    m_lastPlay = bundle.m_lastPlay;    m_filesize = bundle.m_filesize;    m_type = bundle.m_type;    m_exists = bundle.m_exists;    m_isValidMedia = bundle.m_isValidMedia;    m_isCompilation = bundle.m_isCompilation;    m_notCompilation = bundle.m_notCompilation;    m_safeToSave = bundle.m_safeToSave;    m_waitingOnKIO = bundle.m_waitingOnKIO;    m_tempSavePath = bundle.m_tempSavePath;    m_origRenamedSavePath = bundle.m_origRenamedSavePath;    m_tempSaveDigest = bundle.m_tempSaveDigest;    m_saveFileref = bundle.m_saveFileref;    if( bundle.m_moodbar != 0)      {        if( m_moodbar == 0 )          m_moodbar = new Moodbar( this );        *m_moodbar = *bundle.m_moodbar;      }    else      {        // If m_moodbar != 0, it's initialized for a reason        // Deleting it makes the PrettySlider code more ugly,        // since it'd have to reconnect the jobEvent() signal.        if( m_moodbar != 0 )          m_moodbar->reset();      }//    delete m_podcastBundle; why does this crash Amarok? apparently m_podcastBundle isn't always initialized.    m_podcastBundle = 0;    if( bundle.m_podcastBundle )        setPodcastBundle( *bundle.m_podcastBundle );//    delete m_lastFmBundle; same as above    m_lastFmBundle = 0;    if( bundle.m_lastFmBundle )        setLastFmBundle( *bundle.m_lastFmBundle );	m_isSearchDirty = true;    return *this;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?