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 + -
显示快捷键?