metabundle.cpp
来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 1,884 行 · 第 1/5 页
CPP
1,884 行
if( time == Irrelevant ) return i18n( "-" ); QStringList s; s << QString::number( time % 60 ); //seconds time /= 60; if( time ) s << QString::number( time % 60 ); //minutes time /= 60; if( time ) s << QString::number( time % 24 ); //hours time /= 24; if( time ) s << QString::number( time ); //days switch( s.count() ) { case 1: return i18n( "seconds", "%1s" ).arg( s[0] ); case 2: return i18n( "minutes, seconds", "%2m %1s" ).arg( s[0], s[1] ); case 3: return i18n( "hours, minutes, seconds", "%3h %2m %1s" ).arg( s[0], s[1], s[2] ); case 4: return i18n( "days, hours, minutes, seconds", "%4d %3h %2m %1s" ).arg( s[0], s[1], s[2], s[3] ); default: return "omg bug!"; }}QStringMetaBundle::fuzzyTime( int time ){ QString s; int secs=0, min=0, hr=0, day=0, week=0; if( time == Undetermined ) return i18n( "?" ); if( time == Irrelevant ) return i18n( "-" ); secs = time % 60; //seconds time /= 60; min = time % 60; //minutes time /= 60; hr = time % 24 ; //hours time /= 24; day = time % 7 ; //days time /= 7; week = time; //weeks if( week && hr >= 12 ) { day++; if( day == 7 ) { week++; day = 0; } } else if( day && min >= 30 ) { hr++; if( hr == 24 ) { day++; hr = 0; } } else if( hr && secs >= 30 ) { min++; if( min == 60 ) { hr++; min = 0; } } QString weeks = i18n( "1 week %1", "%n weeks %1", week ); QString days = i18n( "1 day %1", "%n days %1", day ); QString hours = i18n( "1 hour", "%n hours", hr ); if( week ) return weeks.arg( day ? days.arg("") : "" ).simplifyWhiteSpace(); else if ( day ) return days.arg( hr ? hours : "" ).simplifyWhiteSpace(); else if ( hr ) return i18n( "%1:%2 hours" ).arg( hr ).arg( zeroPad( min ) ); else return i18n( "%1:%2").arg( min ).arg( zeroPad( secs ) );}QStringMetaBundle::prettyBitrate( int i ){ //the point here is to force sharing of these strings returned from prettyBitrate() static const QString bitrateStore[9] = { "?", "32", "64", "96", "128", "160", "192", "224", "256" }; return (i >=0 && i <= 256 && i % 32 == 0) ? bitrateStore[ i / 32 ] : prettyGeneric( "%1", i );}QStringMetaBundle::prettyFilesize( int s ){ return KIO::convertSize( s );}QStringMetaBundle::prettyRating( int r, bool trailingzero ) //static{ if( trailingzero ) return QString::number( float( r ) / 2, 'f', 1 ); else return r ? QString::number( float( r ) / 2 ) : QString();}QStringMetaBundle::ratingDescription( int r ){ switch( r ) { case 1: return i18n( "Awful" ); case 2: return i18n( "Bad" ); case 3: return i18n( "Barely tolerable" ); case 4: return i18n( "Tolerable" ); case 5: return i18n( "Okay" ); case 6: return i18n( "Good" ); case 7: return i18n( "Very good" ); case 8: return i18n( "Excellent" ); case 9: return i18n( "Amazing" ); case 10: return i18n( "Favorite" ); case 0: default: return i18n( "Not rated" ); // assume weird values as not rated } return "if you can see this, then that's a bad sign.";}QStringListMetaBundle::ratingList(){ QString s = i18n( "rating - description", "%1 - %2" ); QStringList list; list += ratingDescription( 0 ); for ( int i = 1; i<=10; i++ ) list += s.arg( prettyRating( i, true ) ).arg( ratingDescription( i ) ); return list;}QStringListMetaBundle::genreList() //static{ QStringList list; TagLib::StringList genres = TagLib::ID3v1::genreList(); for( TagLib::StringList::ConstIterator it = genres.begin(), end = genres.end(); it != end; ++it ) list += TStringToQString( (*it) ); list.sort(); return list;}voidMetaBundle::setExtendedTag( TagLib::File *file, int tag, const QString value ){ const char *id = 0; if ( m_type == mp3 ) { switch( tag ) { case ( composerTag ): id = "TCOM"; break; case ( discNumberTag ): id = "TPOS"; break; case ( bpmTag ): id = "TBPM"; break; case ( compilationTag ): id = "TCMP"; break; case ( albumArtistTag ): id = "TPE2"; break; // non-standard: Apple, Microsoft } fprintf(stderr, "Setting extended tag %s to %s\n", id, value.utf8().data()); TagLib::MPEG::File *mpegFile = dynamic_cast<TagLib::MPEG::File *>( file ); if ( mpegFile && mpegFile->ID3v2Tag() ) { if ( value.isEmpty() ) mpegFile->ID3v2Tag()->removeFrames( id ); else { if( !mpegFile->ID3v2Tag()->frameListMap()[id].isEmpty() ) mpegFile->ID3v2Tag()->frameListMap()[id].front()->setText( QStringToTString( value ) ); else { TagLib::ID3v2::TextIdentificationFrame *frame = new TagLib::ID3v2::TextIdentificationFrame( id, TagLib::ID3v2::FrameFactory::instance()->defaultTextEncoding() ); frame->setText( QStringToTString( value ) ); mpegFile->ID3v2Tag()->addFrame( frame ); } } } } else if ( m_type == ogg ) { switch( tag ) { case ( composerTag ): id = "COMPOSER"; break; case ( discNumberTag ): id = "DISCNUMBER"; break; case ( bpmTag ): id = "BPM"; break; case ( compilationTag ): id = "COMPILATION"; break; case ( albumArtistTag ): id = "ALBUMARTIST"; break; // non-standard: Amarok } TagLib::Ogg::Vorbis::File *oggFile = dynamic_cast<TagLib::Ogg::Vorbis::File *>( file ); if ( oggFile && oggFile->tag() ) { value.isEmpty() ? oggFile->tag()->removeField( id ): oggFile->tag()->addField( id, QStringToTString( value ), true ); } } else if ( m_type == flac ) { switch( tag ) { case ( composerTag ): id = "COMPOSER"; break; case ( discNumberTag ): id = "DISCNUMBER"; break; case ( bpmTag ): id = "BPM"; break; case ( compilationTag ): id = "COMPILATION"; break; case ( albumArtistTag ): id = "ALBUMARTIST"; break; // non-standard: Amarok } TagLib::FLAC::File *flacFile = dynamic_cast<TagLib::FLAC::File *>( file ); if ( flacFile && flacFile->xiphComment() ) { value.isEmpty() ? flacFile->xiphComment()->removeField( id ): flacFile->xiphComment()->addField( id, QStringToTString( value ), true ); } } else if ( m_type == mp4 ) { TagLib::MP4::Tag *mp4tag = dynamic_cast<TagLib::MP4::Tag *>( file->tag() ); if( mp4tag ) { switch( tag ) { case ( composerTag ): mp4tag->setComposer( QStringToTString( value ) ); break; case ( discNumberTag ): mp4tag->setDisk( value.toInt() ); case ( bpmTag ): mp4tag->setBpm( value.toInt() ); // mp4 doesn't support float bpm case ( compilationTag ): mp4tag->setCompilation( value.toInt() == CompilationYes ); } } }}voidMetaBundle::setPodcastBundle( const PodcastEpisodeBundle &peb ){ delete m_podcastBundle; m_podcastBundle = new PodcastEpisodeBundle; *m_podcastBundle = peb;}voidMetaBundle::setLastFmBundle( const LastFm::Bundle &last ){ delete m_lastFmBundle; // m_lastFmBundle = new LastFm::Bundle(last); m_lastFmBundle = new LastFm::Bundle; *m_lastFmBundle = last;}void MetaBundle::loadImagesFromTag( const TagLib::ID3v2::Tag &tag, EmbeddedImageList& images ) const{ TagLib::ID3v2::FrameList l = tag.frameListMap()[ "APIC" ]; foreachType( TagLib::ID3v2::FrameList, l ) { debug() << "Found APIC frame" << endl; TagLib::ID3v2::AttachedPictureFrame *ap = static_cast<TagLib::ID3v2::AttachedPictureFrame*>( *it ); const TagLib::ByteVector &imgVector = ap->picture(); debug() << "Size of image: " << imgVector.size() << " byte" << endl; // ignore APIC frames without picture and those with obviously bogus size if( imgVector.size() > 0 && imgVector.size() < 10000000 /*10MB*/ ) { images.push_back( EmbeddedImage( imgVector, ap->description() ) ); } }}boolMetaBundle::safeSave(){ bool noproblem; MetaBundleSaver mbs( this ); TagLib::FileRef* fileref = mbs.prepareToSave(); if( !fileref ) { debug() << "Could not get a fileref!" << endl; mbs.cleanupSave(); return false; } noproblem = save( fileref ); if( !noproblem ) { debug() << "MetaBundle::save() didn't work!" << endl; mbs.cleanupSave(); return false; } noproblem = mbs.doSave(); if( !noproblem ) { debug() << "Something failed during the save, cleaning up and exiting!" << endl; mbs.cleanupSave(); return false; } setUniqueId( readUniqueId() ); if( CollectionDB::instance()->isFileInCollection( url().path() ) ) CollectionDB::instance()->doAFTStuff( this, false ); noproblem = mbs.cleanupSave(); return noproblem;}boolMetaBundle::save( TagLib::FileRef* fileref ){ DEBUG_BLOCK if( !isFile() ) return false; //Set default codec to UTF-8 (see bugs 111246 and 111232) TagLib::ID3v2::FrameFactory::instance()->setDefaultTextEncoding(TagLib::String::UTF8); bool passedin = fileref; bool returnval = false; TagLib::FileRef* f; if( !passedin ) f = new TagLib::FileRef( QFile::encodeName( url().path() ), false ); else f = fileref; if ( f && !f->isNull() ) { TagLib::Tag * t = f->tag(); if ( t ) { // f.tag() can return null if the file couldn't be opened for writing t->setTitle( QStringToTString( title().stripWhiteSpace() ) ); t->setArtist( QStringToTString( artist().string().stripWhiteSpace() ) ); t->setAlbum( QStringToTString( album().string().stripWhiteSpace() ) ); t->setTrack( track() ); t->setYear( year() ); t->setComment( QStringToTString( comment().string().stripWhiteSpace() ) ); t->setGenre( QStringToTString( genre().string().stripWhiteSpace() ) ); if ( hasExtendedMetaInformation() ) { setExtendedTag( f->file(), albumArtistTag, albumArtist() ); setExtendedTag( f->file(), composerTag, composer().string().stripWhiteSpace() ); setExtendedTag( f->file(), discNumberTag, discNumber() ? QString::number( discNumber() ) : QString() ); setExtendedTag( f->file(), bpmTag, bpm() ? QString::number( bpm() ) : QString() ); if ( compilation() != CompilationUnknown ) setExtendedTag( f->file(), compilationTag, QString::number( compilation() ) ); } if( !passedin ) { returnval = f->save(); setUniqueId( readUniqueId() ); if( returnval && CollectionDB::instance()->isFileInCollection( url().path() ) ) CollectionDB::instance()->doAFTStuff( this, false ); } else returnval = true; } } if ( !passedin ) delete f; return returnval;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?