tagdialog.cpp
来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 1,499 行 · 第 1/4 页
CPP
1,499 行
QDomDocument doc; if( doc.setContent( xml ) ) m_lyrics = doc.documentElement().text(); else m_lyrics = QString::null;}voidTagDialog::loadLabels( const KURL &url ){ DEBUG_BLOCK m_labels = labelsForURL( url ); originalLabels[ url.path() ] = m_labels; QString text; foreach( m_labels ) { if ( !text.isEmpty() ) text.append( ", " ); text.append( *it ); } kTextEdit_selectedLabels->setText( text ); m_commaSeparatedLabels = text;}MetaBundleTagDialog::bundleForURL( const KURL &url ){ if( storedTags.find( url.path() ) != storedTags.end() ) return storedTags[ url.path() ]; return MetaBundle( url, url.isLocalFile() );}floatTagDialog::scoreForURL( const KURL &url ){ if( storedScores.find( url.path() ) != storedScores.end() ) return storedScores[ url.path() ]; return CollectionDB::instance()->getSongPercentage( url.path() );}intTagDialog::ratingForURL( const KURL &url ){ if( storedRatings.find( url.path() ) != storedRatings.end() ) return storedRatings[ url.path() ]; return CollectionDB::instance()->getSongRating( url.path() );}QStringTagDialog::lyricsForURL( const KURL &url ){ if( storedLyrics.find( url.path() ) != storedLyrics.end() ) return storedLyrics[ url.path() ]; return CollectionDB::instance()->getLyrics( url.path() );}QStringListTagDialog::labelsForURL( const KURL &url ){ if( newLabels.find( url.path() ) != newLabels.end() ) return newLabels[ url.path() ]; if( originalLabels.find( url.path() ) != originalLabels.end() ) return originalLabels[ url.path() ]; QStringList tmp = CollectionDB::instance()->getLabels( url.path(), CollectionDB::typeUser ); originalLabels[ url.path() ] = tmp; return tmp;}voidTagDialog::saveTags(){ if( !m_perTrack ) { applyToAllTracks(); } else { storeTags(); } QMap<QString, float>::ConstIterator endScore( storedScores.end() ); for(QMap<QString, float>::ConstIterator it = storedScores.begin(); it != endScore; ++it ) { CollectionDB::instance()->setSongPercentage( it.key(), it.data() ); } QMap<QString, int>::ConstIterator endRating( storedRatings.end() ); for(QMap<QString, int>::ConstIterator it = storedRatings.begin(); it != endRating; ++it ) { CollectionDB::instance()->setSongRating( it.key(), it.data() ); } QMap<QString, QString>::ConstIterator endLyrics( storedLyrics.end() ); for(QMap<QString, QString>::ConstIterator it = storedLyrics.begin(); it != endLyrics; ++it ) { CollectionDB::instance()->setLyrics( it.key(), it.data(), CollectionDB::instance()->uniqueIdFromUrl( KURL( it.key() ) ) ); emit lyricsChanged( it.key() ); } QMap<QString, QStringList>::ConstIterator endLabels( newLabels.end() ); for(QMap<QString, QStringList>::ConstIterator it = newLabels.begin(); it != endLabels; ++it ) { CollectionDB::instance()->setLabels( it.key(), it.data(), CollectionDB::instance()->uniqueIdFromUrl( KURL( it.key() ) ), CollectionDB::typeUser ); } CollectionDB::instance()->cleanLabels(); ThreadManager::instance()->queueJob( new TagDialogWriter( storedTags ) );}voidTagDialog::applyToAllTracks(){ generateDeltaForLabelList( labelListFromText( kTextEdit_selectedLabels->text() ) ); const KURL::List::ConstIterator end = m_urlList.end(); for ( KURL::List::ConstIterator it = m_urlList.begin(); it != end; ++it ) { /* we have to update the values if they changed, so: 1) !kLineEdit_field->text().isEmpty() && kLineEdit_field->text() != mb.field i.e.: The user wrote something on the field, and it's different from what we have in the tag. 2) !m_bundle.field().isEmpty() && kLineEdit_field->text().isEmpty() i.e.: The user was shown some value for the field (it was the same for all selected tracks), and he deliberately emptied it. TODO: All this mess is because the dialog uses "" to represent what the user doesn't want to change, maybe we can think of something better? */ MetaBundle mb = bundleForURL( *it ); int changed = 0; if( !kComboBox_artist->currentText().isEmpty() && kComboBox_artist->currentText() != mb.artist() || kComboBox_artist->currentText().isEmpty() && !m_bundle.artist().isEmpty() ) { mb.setArtist( kComboBox_artist->currentText() ); changed |= TagDialog::TAGSCHANGED; } if( !kComboBox_album->currentText().isEmpty() && kComboBox_album->currentText() != mb.album() || kComboBox_album->currentText().isEmpty() && !m_bundle.album().isEmpty() ) { mb.setAlbum( kComboBox_album->currentText() ); changed |= TagDialog::TAGSCHANGED; } if( !kComboBox_genre->currentText().isEmpty() && kComboBox_genre->currentText() != mb.genre() || kComboBox_genre->currentText().isEmpty() && !m_bundle.genre().isEmpty() ) { mb.setGenre( kComboBox_genre->currentText() ); changed |= TagDialog::TAGSCHANGED; } if( !kTextEdit_comment->text().isEmpty() && kTextEdit_comment->text() != mb.comment() || kTextEdit_comment->text().isEmpty() && !m_bundle.comment().isEmpty() ) { mb.setComment( kTextEdit_comment->text() ); changed |= TagDialog::TAGSCHANGED; } if( !kComboBox_composer->currentText().isEmpty() && kComboBox_composer->currentText() != mb.composer() || kComboBox_composer->currentText().isEmpty() && !m_bundle.composer().isEmpty() ) { mb.setComposer( kComboBox_composer->currentText() ); changed |= TagDialog::TAGSCHANGED; } if( kIntSpinBox_year->value() && kIntSpinBox_year->value() != mb.year() || !kIntSpinBox_year->value() && m_bundle.year() ) { mb.setYear( kIntSpinBox_year->value() ); changed |= TagDialog::TAGSCHANGED; } if( kIntSpinBox_discNumber->value() && kIntSpinBox_discNumber->value() != mb.discNumber() || !kIntSpinBox_discNumber->value() && m_bundle.discNumber() ) { mb.setDiscNumber( kIntSpinBox_discNumber->value() ); changed |= TagDialog::TAGSCHANGED; } if( kIntSpinBox_score->value() && kIntSpinBox_score->value() != mb.score() || !kIntSpinBox_score->value() && m_bundle.score() ) { mb.setScore( kIntSpinBox_score->value() ); changed |= TagDialog::SCORECHANGED; } if( kComboBox_rating->currentItem() && kComboBox_rating->currentItem() != m_bundle.rating() || !kComboBox_rating->currentItem() && m_bundle.rating() ) { mb.setRating( kComboBox_rating->currentItem() ); changed |= TagDialog::RATINGCHANGED; } storeTags( *it, changed, mb ); QStringList tmpLabels = labelsForURL( *it ); //apply delta for( QStringList::Iterator iter = m_removedLabels.begin(); iter != m_removedLabels.end(); ++iter ) { tmpLabels.remove( *iter ); } for( QStringList::Iterator iter = m_addedLabels.begin(); iter != m_addedLabels.end(); ++iter ) { if( tmpLabels.find( *iter ) == tmpLabels.end() ) tmpLabels.append( *iter ); } storeLabels( *it, tmpLabels ); }}QStringListTagDialog::labelListFromText( const QString &text ){ QStringList tmp = QStringList::split( ',', text ); //insert each string into a map to remove duplicates QMap<QString, int> map; foreach( tmp ) { QString tmpString = (*it).stripWhiteSpace(); if ( !tmpString.isEmpty() ) map.replace( tmpString, 0 ); } QStringList result; QMap<QString, int>::ConstIterator endMap( map.end() ); for(QMap<QString, int>::ConstIterator it = map.begin(); it != endMap; ++it ) { result.append( it.key() ); } return result;}voidTagDialog::generateDeltaForLabelList( const QStringList &list ){ m_addedLabels.clear(); m_removedLabels.clear(); foreach( list ) { if ( !m_labels.contains( *it ) ) m_addedLabels.append( *it ); } foreach( m_labels ) { if ( !list.contains( *it ) ) m_removedLabels.append( *it ); } m_labels = list;}QStringTagDialog::generateHTML( const QStringList &labels ){ //the first column of each row is the label name, the second the number of assigned songs //loop through it to find the highest number of songs, can be removed if somebody figures out a better sql query QMap<QString, QPair<QString, int> > mapping; QStringList sortedLabels; int max = 1; foreach( labels ) { QString label = *it; sortedLabels << label.lower(); ++it; int value = ( *it ).toInt(); if ( value > max ) max = value; mapping[label.lower()] = QPair<QString, int>( label, value ); } sortedLabels.sort(); QString html = "<html><body>"; foreach( sortedLabels ) { QString key = *it; //generate a number in the range 1..10 based on how much the label is used int labelUse = ( mapping[key].second * 10 ) / max; if ( labelUse == 0 ) labelUse = 1; html.append( QString( "<span class='label size%1'><a href=\"label:%2\">%3</a></span> " ) .arg( QString::number( labelUse ), mapping[key].first, mapping[key].first ) ); } html.append( "</html></body>" ); debug() << "Dumping HTML for label cloud: " << html << endl; return html;}voidTagDialog::openURLRequest(const KURL &url ) //SLOT{ DEBUG_BLOCK if ( url.protocol() == "label" ) { QString text = kTextEdit_selectedLabels->text(); QStringList currentLabels = labelListFromText( text ); if ( currentLabels.contains( url.path() ) ) return; if ( !text.isEmpty() ) text.append( ", " ); text.append( url.path() ); kTextEdit_selectedLabels->setText( text ); }}boolTagDialog::writeTag( MetaBundle &mb, bool updateCB ){ QCString path = QFile::encodeName( mb.url().path() ); if ( !TagLib::File::isWritable( path ) ) { Amarok::StatusBar::instance()->longMessage( i18n( "The file %1 is not writable." ).arg( mb.url().fileName() ), KDE::StatusBar::Error ); return false; } //visual feedback QApplication::setOverrideCursor( KCursor::waitCursor() ); bool result = mb.save(); mb.updateFilesize(); if( result ) //update the collection db CollectionDB::instance()->updateTags( mb.url().path(), mb, updateCB ); QApplication::restoreOverrideCursor(); return result;}TagDialogWriter::TagDialogWriter( const QMap<QString, MetaBundle> tagsToChange ) : ThreadManager::Job( "TagDialogWriter" ), m_successCount ( 0 ), m_failCount ( 0 ){ QApplication::setOverrideCursor( KCursor::waitCursor() ); QMap<QString, MetaBundle>::ConstIterator end = tagsToChange.end(); for(QMap<QString, MetaBundle>::ConstIterator it = tagsToChange.begin(); it != end; ++it ) { MetaBundle mb = it.data(); mb.detach(); m_tags += mb; }}boolTagDialogWriter::doJob(){ for( int i = 0, size=m_tags.size(); i<size; ++i ) { QCString path = QFile::encodeName( m_tags[i].url().path() ); if ( !TagLib::File::isWritable( path ) ) { Amarok::StatusBar::instance()->longMessageThreadSafe( i18n( "The file %1 is not writable." ).arg( m_tags[i].url().fileName() ), KDE::StatusBar::Error ); m_failed += true; continue; } bool result = m_tags[i].save(); m_tags[i].updateFilesize(); if( result ) m_successCount++; else { m_failCount++; m_failedURLs += m_tags[i].prettyURL(); } m_failed += !result; } return true;}voidTagDialogWriter::completeJob(){ for( int i = 0, size=m_tags.size(); i<size; ++i ) { if ( !m_failed[i] ) { CollectionDB::instance()->updateTags( m_tags[i].url().path(), m_tags[i], false /* don't update browsers*/ ); Playlist::instance()->updateMetaData( m_tags[i] ); } } QApplication::restoreOverrideCursor(); if ( m_successCount ) CollectionView::instance()->databaseChanged(); if ( m_failCount ) Amarok::StatusBar::instance()->longMessage( i18n( "Sorry, the tag for the following files could not be changed:\n" ).arg( m_failedURLs.join( ";\n" ) ), KDE::StatusBar::Error );}#include "tagdialog.moc"
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?