Hi, I've written a Patch to fix this bug: http://bugs.kde.org/213074 I've also refactored the code in order to reuse some of the code originally intended for the MusicBrainz tag guesser. I'd like to know what you think.
Cheers Matthias
>From 39d667ed3b8c4321459ca0abf6522ac76f920d2c Mon Sep 17 00:00:00 2001 From: Matthias Berndt <matthias_ber...@gmx.de> Date: Thu, 2 Aug 2012 20:06:48 +0200 Subject: [PATCH 1/2] make the tag guessing dialog non-modal --- src/dialogs/TagDialog.cpp | 160 ++++++++++++++++++++++++---------------------- src/dialogs/TagDialog.h | 2 + 2 Dateien geändert, 85 Zeilen hinzugefügt(+), 77 Zeilen entfernt(-) diff --git a/src/dialogs/TagDialog.cpp b/src/dialogs/TagDialog.cpp index a448458..f306473 100644 --- a/src/dialogs/TagDialog.cpp +++ b/src/dialogs/TagDialog.cpp @@ -412,86 +412,92 @@ TagDialog::labelSelected() //SLOT ui->removeButton->setEnabled( ui->labelsList->selectionModel()->hasSelection() ); } +void TagDialog::onFilenameSchemeChanged() //SLOT +{ + KDialog *dialog = qobject_cast<KDialog*>(sender()); + Q_ASSERT(dialog); + FilenameLayoutDialog *widget = qobject_cast<FilenameLayoutDialog*>(dialog->mainWidget()); + Q_ASSERT(widget); + + int cur = 0; + + TagGuesser guesser; + guesser.setFilename( widget->getParsableFileName() ); + guesser.setSchema( widget->getParsableScheme() ); + guesser.setCaseType( widget->getCaseOptions() ); + guesser.setConvertUnderscores( widget->getUnderscoreOptions() ); + guesser.setCutTrailingSpaces( widget->getWhitespaceOptions() ); + + if( guesser.guess() ) + { + QMap<qint64,QString> Tags = guesser.tags(); + + if( Tags.contains( Meta::valTitle ) ) + ui->kLineEdit_title->setText( Tags[Meta::valTitle] ); + + if( Tags.contains( Meta::valArtist ) ) + { + cur = ui->kComboBox_artist->currentIndex(); + ui->kComboBox_artist->setItemText( cur, Tags[Meta::valArtist] ); + } + + if( Tags.contains( Meta::valAlbum ) ) + { + cur = ui->kComboBox_album->currentIndex(); + ui->kComboBox_album->setItemText( cur, Tags[Meta::valAlbum] ); + } + + if( Tags.contains( Meta::valAlbumArtist ) ) + { + cur = ui->kComboBox_albumArtist->currentIndex(); + ui->kComboBox_albumArtist->setItemText( cur, Tags[Meta::valAlbumArtist] ); + } + + if( Tags.contains( Meta::valTrackNr ) ) + ui->qSpinBox_track->setValue( Tags[Meta::valTrackNr].toInt() ); + + if( Tags.contains( Meta::valComment ) ) + ui->qPlainTextEdit_comment->setPlainText( Tags[Meta::valComment] ); + + if( Tags.contains( Meta::valYear ) ) + ui->qSpinBox_year->setValue( Tags[Meta::valYear].toInt() ); + + if( Tags.contains( Meta::valComposer ) ) + { + cur = ui->kComboBox_composer->currentIndex(); + ui->kComboBox_composer->setItemText( cur, Tags[Meta::valComposer] ); + } + + if( Tags.contains( Meta::valGenre ) ) + { + cur = ui->kComboBox_genre->currentIndex(); + ui->kComboBox_genre->setItemText( cur, Tags[Meta::valGenre] ); + } + + if( Tags.contains( Meta::valDiscNr ) ) + { + ui->qSpinBox_discNumber->setValue( Tags[Meta::valDiscNr].toInt() ); + } + } + else + { + debug() << "guessing tags from filename failed" << endl; + } +} + //creates a KDialog and executes the FilenameLayoutDialog. Grabs a filename scheme, extracts tags (via TagGuesser) from filename and fills the appropriate fields on TagDialog. void TagDialog::guessFromFilename() //SLOT { - KDialog dialog; - dialog.setCaption( i18n( "Filename Layout Chooser" ) ); - dialog.setButtons( KDialog::Ok | KDialog::Cancel ); - FilenameLayoutDialog widget( &dialog ); - widget.setFileName( m_currentTrack->playableUrl().path() ); - dialog.setMainWidget( &widget ); - - if( dialog.exec() == KDialog::Accepted ) - { - widget.onAccept(); - - int cur = 0; - - TagGuesser guesser; - guesser.setFilename( widget.getParsableFileName() ); - guesser.setSchema( widget.getParsableScheme() ); - guesser.setCaseType( widget.getCaseOptions() ); - guesser.setConvertUnderscores( widget.getUnderscoreOptions() ); - guesser.setCutTrailingSpaces( widget.getWhitespaceOptions() ); - - if( guesser.guess() ) - { - QMap<qint64,QString> Tags = guesser.tags(); - - if( Tags.contains( Meta::valTitle ) ) - ui->kLineEdit_title->setText( Tags[Meta::valTitle] ); - - if( Tags.contains( Meta::valArtist ) ) - { - cur = ui->kComboBox_artist->currentIndex(); - ui->kComboBox_artist->setItemText( cur, Tags[Meta::valArtist] ); - } - - if( Tags.contains( Meta::valAlbum ) ) - { - cur = ui->kComboBox_album->currentIndex(); - ui->kComboBox_album->setItemText( cur, Tags[Meta::valAlbum] ); - } - - if( Tags.contains( Meta::valAlbumArtist ) ) - { - cur = ui->kComboBox_albumArtist->currentIndex(); - ui->kComboBox_albumArtist->setItemText( cur, Tags[Meta::valAlbumArtist] ); - } - - if( Tags.contains( Meta::valTrackNr ) ) - ui->qSpinBox_track->setValue( Tags[Meta::valTrackNr].toInt() ); - - if( Tags.contains( Meta::valComment ) ) - ui->qPlainTextEdit_comment->setPlainText( Tags[Meta::valComment] ); - - if( Tags.contains( Meta::valYear ) ) - ui->qSpinBox_year->setValue( Tags[Meta::valYear].toInt() ); - - if( Tags.contains( Meta::valComposer ) ) - { - cur = ui->kComboBox_composer->currentIndex(); - ui->kComboBox_composer->setItemText( cur, Tags[Meta::valComposer] ); - } - - if( Tags.contains( Meta::valGenre ) ) - { - cur = ui->kComboBox_genre->currentIndex(); - ui->kComboBox_genre->setItemText( cur, Tags[Meta::valGenre] ); - } - - if( Tags.contains( Meta::valDiscNr ) ) - { - ui->qSpinBox_discNumber->setValue( Tags[Meta::valDiscNr].toInt() ); - } - } - else - { - debug() << "guessing tags from filename failed" << endl; - } - } + KDialog *dialog = new KDialog(this); + dialog->setCaption( i18n( "Filename Layout Chooser" ) ); + dialog->setButtons( KDialog::Ok | KDialog::Cancel ); + FilenameLayoutDialog *widget = new FilenameLayoutDialog( dialog ); + widget->setFileName( m_currentTrack->playableUrl().path() ); + dialog->setMainWidget( widget ); + connect(dialog, SIGNAL(okClicked()), widget, SLOT(onAccept())); + connect(dialog, SIGNAL(okClicked()), this, SLOT(onFilenameSchemeChanged())); + dialog->show(); } //////////////////////////////////////////////////////////////////////////////// @@ -1266,7 +1272,7 @@ TagDialog::setControlsAccessability() ui->kLineEdit_Bpm->setClearButtonShown( editable ); ui->qPlainTextEdit_comment->setEnabled( editable ); - ui->pushButton_guessTags->setEnabled( m_perTrack && editable ); + ui->pushButton_guessTags->setEnabled( editable ); ui->pushButton_musicbrainz->setEnabled( editable ); } diff --git a/src/dialogs/TagDialog.h b/src/dialogs/TagDialog.h index 015f2d3..ff24745 100644 --- a/src/dialogs/TagDialog.h +++ b/src/dialogs/TagDialog.h @@ -124,6 +124,8 @@ class AMAROK_EXPORT TagDialog : public KDialog, public Meta::Observer */ void labelSelected(); + void onFilenameSchemeChanged(); + private: /** Sets some further properties and connects all the signals */ void initUi(); -- 1.7.11.2 >From 334cbafa4fed328956a46d26fb581cbfdfb4ef66 Mon Sep 17 00:00:00 2001 From: Matthias Berndt <matthias_ber...@gmx.de> Date: Fri, 3 Aug 2012 15:52:25 +0200 Subject: [PATCH 2/2] Allow guessing of tags from filenames for multiple files (bug #213074). Refactor some of the code in order to reuse some of the code intended for MusicBrainz --- shared/TagsFromFileNameGuesser.cpp | 14 +- src/core/meta/support/MetaConstants.cpp | 38 ++++ src/core/meta/support/MetaConstants.h | 8 + src/dialogs/FilenameLayoutDialog.cpp | 59 ++---- src/dialogs/TagDialog.cpp | 322 ++++++++++++++------------------ src/dialogs/TagDialog.h | 2 +- src/dialogs/TagGuesser.cpp | 70 ++----- src/dialogs/TagGuesser.h | 15 +- 8 Dateien geändert, 234 Zeilen hinzugefügt(+), 294 Zeilen entfernt(-) diff --git a/shared/TagsFromFileNameGuesser.cpp b/shared/TagsFromFileNameGuesser.cpp index f2ec2ba..acb028a 100644 --- a/shared/TagsFromFileNameGuesser.cpp +++ b/shared/TagsFromFileNameGuesser.cpp @@ -65,11 +65,11 @@ fieldName( const QString &field ) return 0; } -QList< qint64 > +QList<QPair<qint64, QVariant::Type> > parseTokens( const QString &scheme ) { QRegExp rxm( "%(\\w+)%" ); - QList< qint64 > tokens; + QList<QPair<qint64, QVariant::Type> > tokens; int pos = 0; qint64 field; @@ -77,7 +77,7 @@ parseTokens( const QString &scheme ) { field = fieldName( rxm.cap( 1 ) ); if( field ) - tokens << field; + tokens << qMakePair( field, m_digitalFields.exactMatch( "%" + rxm.cap( 1 ) + "%" ) ? QVariant::Int : QVariant::String ); pos += rxm.matchedLength(); } @@ -96,11 +96,11 @@ Meta::Tag::TagGuesser::guessTagsByScheme( const QString &fileName, const QString QString m_fileName = fileName; QString m_scheme = scheme; - QList< qint64 > tokens = parseTokens( m_scheme ); + QList<QPair<qint64, QVariant::Type> > tokens = parseTokens( m_scheme ); // Screen all special symbols if( !isRegExp ) - m_scheme = m_scheme.replace( QRegExp( "([~!\\^&*()\\-+\\[\\]{}\\\\:\"?\\.])" ),"\\\\1" ); + m_scheme = QRegExp::escape( m_scheme ); QRegExp spaces( "(\\s+)" ); rx.setPattern( m_scheme.replace( spaces, "\\s+" ) @@ -119,7 +119,9 @@ Meta::Tag::TagGuesser::guessTagsByScheme( const QString &fileName, const QString value.replace( "_", " " ); if( cutTrailingSpaces ) value = value.trimmed(); - metadata.insert( tokens[i], value ); + QVariant val( value ); + val.convert( tokens[i].second ); + metadata.insert( tokens[i].first, val ); } return metadata; } diff --git a/src/core/meta/support/MetaConstants.cpp b/src/core/meta/support/MetaConstants.cpp index 079fd22..1f3b978 100644 --- a/src/core/meta/support/MetaConstants.cpp +++ b/src/core/meta/support/MetaConstants.cpp @@ -59,6 +59,44 @@ QString Meta::nameForField( qint64 field ) } } +QString Meta::XesamNameForField( qint64 field ) +{ + switch( field ) + { + case Meta::valUrl: return Meta::Field::URL; + case Meta::valTitle: return Meta::Field::TITLE; + case Meta::valArtist: return Meta::Field::ARTIST; + case Meta::valAlbum: return Meta::Field::ALBUM; + case Meta::valGenre: return Meta::Field::GENRE; + case Meta::valComposer: return Meta::Field::COMPOSER; + case Meta::valYear: return Meta::Field::YEAR; + case Meta::valCreateDate: return Meta::Field::YEAR; // what's the difference between valCreateDate and valYear? + case Meta::valComment: return Meta::Field::COMMENT; + case Meta::valTrackNr: return Meta::Field::TRACKNUMBER; + case Meta::valDiscNr: return Meta::Field::DISCNUMBER; + case Meta::valBpm: return Meta::Field::BPM; + case Meta::valLength: return Meta::Field::LENGTH; + case Meta::valBitrate: return Meta::Field::BITRATE; + case Meta::valSamplerate: return Meta::Field::SAMPLERATE; + case Meta::valFilesize: return Meta::Field::FILESIZE; + case Meta::valFormat: return Meta::Field::CODEC; // is this right? + case Meta::valScore: return Meta::Field::SCORE; + case Meta::valRating: return Meta::Field::RATING; + case Meta::valFirstPlayed: return Meta::Field::FIRST_PLAYED; + case Meta::valLastPlayed: return Meta::Field::LAST_PLAYED; + case Meta::valPlaycount: return Meta::Field::PLAYCOUNT; + case Meta::valUniqueId: return Meta::Field::UNIQUEID; + case Meta::valTrackGain: return Meta::Field::TRACKGAIN; + case Meta::valTrackGainPeak: return Meta::Field::TRACKPEAKGAIN; + case Meta::valAlbumGain: return Meta::Field::ALBUMGAIN; + case Meta::valAlbumGainPeak: return Meta::Field::ALBUMPEAKGAIN; + case Meta::valAlbumArtist: return Meta::Field::ALBUMARTIST; + case Meta::valLabel: return Meta::Field::LABELS; + default: return QString(); + // There don't seem to be a suitable Xesam name for valModified. Tough. + } +} + qint64 Meta::fieldForName( const QString &name ) { if( name.compare( "anything", Qt::CaseInsensitive ) == 0 diff --git a/src/core/meta/support/MetaConstants.h b/src/core/meta/support/MetaConstants.h index 41c78a9..0f0e51c 100644 --- a/src/core/meta/support/MetaConstants.h +++ b/src/core/meta/support/MetaConstants.h @@ -31,6 +31,8 @@ namespace Meta */ AMAROK_CORE_EXPORT QString nameForField( qint64 field ); + AMAROK_CORE_EXPORT QString XesamNameForField( qint64 field ); + /** The inverse of nameForField */ AMAROK_CORE_EXPORT qint64 fieldForName( const QString &name ); @@ -98,9 +100,15 @@ namespace Meta static const QString LAST_PLAYED = "xesam:lastUsed"; static const QString UNIQUEID = "xesam:id"; + static const QString LYRICS = "xesam::asText"; // new static const QString COMPILATION = "xesam:compilation"; + + static const QString LABELS = "labels"; + + static const QString TYPE = "type"; + static const QString COLLECTION = "collection"; } } diff --git a/src/dialogs/FilenameLayoutDialog.cpp b/src/dialogs/FilenameLayoutDialog.cpp index 1517a8a..211faed 100644 --- a/src/dialogs/FilenameLayoutDialog.cpp +++ b/src/dialogs/FilenameLayoutDialog.cpp @@ -22,6 +22,7 @@ #include "core/support/Amarok.h" #include "core/support/Debug.h" #include "shared/MetaValues.h" +#include "core/meta/support/MetaConstants.h" #include <KConfig> #include <KColorScheme> @@ -232,52 +233,22 @@ FilenameLayoutDialog::updatePreview() //SLOT if( guesser.guess() ) { - QMap<qint64,QString> tags = guesser.tags(); + QVariantMap tags = guesser.tags(); - if( tags.contains( Meta::valAlbum ) ) - Album_result->setText( "<font color='" + QColor( album_color ).name() + "'>" + tags[Meta::valAlbum] + "</font>" ); - else - Album_result->setText( i18nc( "Text to represent an empty tag. Braces (<>) are only to clarify emptiness.", "<empty>" ) ); - - if( tags.contains( Meta::valAlbumArtist ) ) - AlbumArtist_result->setText( "<font color='" + QColor( albumartist_color ).name() + "'>" + tags[Meta::valAlbumArtist] + "</font>" ); - else - AlbumArtist_result->setText( i18nc( "Text to represent an empty tag. Braces (<>) are only to clarify emptiness.", "<empty>" ) ); - - if( tags.contains( Meta::valTitle ) ) - Title_result->setText( "<font color='" + QColor( title_color ).name() + "'>" + tags[Meta::valTitle] + "</font>" ); - else - Title_result->setText( i18nc( "Text to represent an empty tag. Braces (<>) are only to clarify emptiness.", "<empty>" ) ); - - if( tags.contains( Meta::valArtist ) ) - Artist_result->setText( "<font color='" + QColor( artist_color ).name() + "'>" + tags[Meta::valArtist] + "</font>" ); - else - Artist_result->setText( i18nc( "Text to represent an empty tag. Braces (<>) are only to clarify emptiness.", "<empty>" ) ); - - if( tags.contains( Meta::valComment ) ) - Comment_result->setText( "<font color='" + QColor( comment_color ).name() + "'>" + tags[Meta::valComment] + "</font>" ); - else - Comment_result->setText( i18nc( "Text to represent an empty tag. Braces (<>) are only to clarify emptiness.", "<empty>" ) ); + QPair<QString, QLabel*> fields[] = { qMakePair( Meta::Field::ALBUM, Album_result ), + qMakePair( Meta::Field::ALBUMARTIST, AlbumArtist_result ), qMakePair( Meta::Field::TITLE, Title_result ), + qMakePair( Meta::Field::ARTIST, Artist_result ), qMakePair( Meta::Field::COMMENT, Comment_result ), + qMakePair( Meta::Field::COMPOSER, Composer_result ), qMakePair( Meta::Field::GENRE, Genre_result ), + qMakePair( Meta::Field::TRACKNUMBER, Track_result ), qMakePair( Meta::Field::YEAR, Year_result ) }; - if( tags.contains( Meta::valComposer ) ) - Composer_result->setText( "<font color='" + QColor( composer_color ).name() + "'>" + tags[Meta::valComposer] + "</font>" ); - else - Composer_result->setText( i18nc( "Text to represent an empty tag. Braces (<>) are only to clarify emptiness.", "<empty>" ) ); - - if( tags.contains( Meta::valGenre ) ) - Genre_result->setText( "<font color='" + QColor( genre_color ).name() + "'>" + tags[Meta::valGenre] + "</font>" ); - else - Genre_result->setText( i18nc( "Text to represent an empty tag. Braces (<>) are only to clarify emptiness.", "<empty>" ) ); - - if( tags.contains( Meta::valTrackNr ) ) - Track_result->setText( "<font color='" + QColor( track_color ).name() + "'>" + tags[Meta::valTrackNr] + "</font>" ); - else - Track_result->setText( i18nc( "Text to represent an empty tag. Braces (<>) are only to clarify emptiness.", "<empty>" ) ); - - if( tags.contains( Meta::valYear ) ) - Year_result->setText( "<font color='" + QColor( year_color ).name() + "'>" + tags[Meta::valYear] + "</font>" ); - else - Year_result->setText( i18nc( "Text to represent an empty tag. Braces (<>) are only to clarify emptiness.", "<empty>" ) ); + for( unsigned i = 0; i < sizeof fields / sizeof *fields; ++i ) + { + QString field = fields[i].first; + QLabel *label = fields[i].second; + label->setText( tags.contains( field ) + ? "<font color='" + QColor(guesser.fieldColor(field)).name() + "'>" + tags[field].toString() + "</font>" + : i18nc( "Text to represent an empty tag. Braces (<>) are only to clarify emptiness.", "<empty>" ) ); + } filenamePreview->setText(guesser.coloredFileName()); } diff --git a/src/dialogs/TagDialog.cpp b/src/dialogs/TagDialog.cpp index f306473..cc09ca4 100644 --- a/src/dialogs/TagDialog.cpp +++ b/src/dialogs/TagDialog.cpp @@ -47,15 +47,6 @@ #include <KRun> -namespace Meta { -namespace Field { - const QString LABELS = "labels"; - const QString LYRICS = "lyrics"; - const QString TYPE = "type"; - const QString COLLECTION = "collection"; -} -} - TagDialog::TagDialog( const Meta::TrackList &tracks, QWidget *parent ) : KDialog( parent ) , m_perTrack( true ) @@ -96,6 +87,7 @@ TagDialog::TagDialog( Meta::TrackPtr track, QWidget *parent ) TagDialog::TagDialog( Collections::QueryMaker *qm ) : KDialog( The::mainWindow() ) + , m_labelModel( 0 ) , m_perTrack( true ) , m_currentTrackNum( 0 ) , m_changed( false ) @@ -108,8 +100,8 @@ TagDialog::TagDialog( Collections::QueryMaker *qm ) resize( minimumSizeHint() ); qm->setQueryType( Collections::QueryMaker::Track ); - connect( qm, SIGNAL( newResultReady( Meta::TrackList ) ), this, SLOT( resultReady( Meta::TrackList ) ), Qt::QueuedConnection ); - connect( qm, SIGNAL( queryDone() ), this, SLOT( queryDone() ), Qt::QueuedConnection ); + connect( qm, SIGNAL( newResultReady( Meta::TrackList ) ), SLOT( resultReady( Meta::TrackList ) ), Qt::QueuedConnection ); + connect( qm, SIGNAL( queryDone() ), SLOT( queryDone() ), Qt::QueuedConnection ); qm->run(); } @@ -245,54 +237,25 @@ TagDialog::dataQueryDone() //but the performance impact should be negligible // we do this because if we insert items and the contents of the textbox // are not in the list, it clears the textbox. which is bad --lfranchi 2.22.09 - QString saveText( ui->kComboBox_artist->lineEdit()->text() ); - QStringList artists = m_artists.toList(); - artists.sort(); - ui->kComboBox_artist->clear(); - ui->kComboBox_artist->insertItems( 0, artists ); - ui->kComboBox_artist->completionObject()->setItems( artists ); - ui->kComboBox_artist->lineEdit()->setText( saveText ); - - saveText = ui->kComboBox_album->lineEdit()->text(); - QStringList albums = m_albums.toList(); - albums.sort(); - ui->kComboBox_album->clear(); - ui->kComboBox_album->insertItems( 0, albums ); - ui->kComboBox_album->completionObject()->setItems( albums ); - ui->kComboBox_album->lineEdit()->setText( saveText ); - - saveText = ui->kComboBox_albumArtist->lineEdit()->text(); - QStringList albumArtists = m_albumArtists.toList(); - albumArtists.sort(); - ui->kComboBox_albumArtist->clear(); - ui->kComboBox_albumArtist->insertItems( 0, albumArtists ); - ui->kComboBox_albumArtist->completionObject()->setItems( albumArtists ); - ui->kComboBox_albumArtist->lineEdit()->setText( saveText ); - - saveText = ui->kComboBox_composer->lineEdit()->text(); - QStringList composers = m_composers.toList(); - composers.sort(); - ui->kComboBox_composer->clear(); - ui->kComboBox_composer->insertItems( 0, composers ); - ui->kComboBox_composer->completionObject()->setItems( composers ); - ui->kComboBox_composer->lineEdit()->setText( saveText ); - - saveText = ui->kComboBox_genre->lineEdit()->text(); - QStringList genres = m_genres.toList(); - genres.sort(); - ui->kComboBox_genre->clear(); - ui->kComboBox_genre->insertItems( 0, genres ); - ui->kComboBox_genre->completionObject()->setItems( genres ); - ui->kComboBox_genre->lineEdit()->setText( saveText ); - - saveText = ui->kComboBox_label->lineEdit()->text(); - QStringList labels = m_allLabels.toList(); - labels.sort(); - ui->kComboBox_label->clear(); - ui->kComboBox_label->insertItems( 0, labels ); - ui->kComboBox_label->completionObject()->setItems( labels ); - ui->kComboBox_label->lineEdit()->setText( saveText ); - + QPair<KComboBox*, QSet<QString>*> boxes[] = + { qMakePair( ui->kComboBox_artist, &m_artists ), + qMakePair( ui->kComboBox_album, &m_albums ), + qMakePair( ui->kComboBox_albumArtist, &m_albumArtists ), + qMakePair( ui->kComboBox_composer, &m_composers ), + qMakePair( ui->kComboBox_genre, &m_genres ), + qMakePair( ui->kComboBox_label, &m_allLabels ) }; + + for( unsigned i = 0; i < sizeof boxes / sizeof *boxes; ++i ) + { + KComboBox &box = *boxes[i].first; + QStringList strings = boxes[i].second->toList(); + QString saveText( box.lineEdit()->text() ); + strings.sort(); + box.clear(); + box.insertItems( 0, strings ); + box.completionObject()->setItems( strings ); + box.lineEdit()->setText( saveText ); + } m_changed = oldChanged; } @@ -412,80 +375,35 @@ TagDialog::labelSelected() //SLOT ui->removeButton->setEnabled( ui->labelsList->selectionModel()->hasSelection() ); } -void TagDialog::onFilenameSchemeChanged() //SLOT +void +TagDialog::filenameSchemeChanged() //SLOT { - KDialog *dialog = qobject_cast<KDialog*>(sender()); - Q_ASSERT(dialog); - FilenameLayoutDialog *widget = qobject_cast<FilenameLayoutDialog*>(dialog->mainWidget()); - Q_ASSERT(widget); - - int cur = 0; - - TagGuesser guesser; - guesser.setFilename( widget->getParsableFileName() ); - guesser.setSchema( widget->getParsableScheme() ); - guesser.setCaseType( widget->getCaseOptions() ); - guesser.setConvertUnderscores( widget->getUnderscoreOptions() ); - guesser.setCutTrailingSpaces( widget->getWhitespaceOptions() ); - - if( guesser.guess() ) - { - QMap<qint64,QString> Tags = guesser.tags(); - - if( Tags.contains( Meta::valTitle ) ) - ui->kLineEdit_title->setText( Tags[Meta::valTitle] ); - - if( Tags.contains( Meta::valArtist ) ) - { - cur = ui->kComboBox_artist->currentIndex(); - ui->kComboBox_artist->setItemText( cur, Tags[Meta::valArtist] ); - } - - if( Tags.contains( Meta::valAlbum ) ) - { - cur = ui->kComboBox_album->currentIndex(); - ui->kComboBox_album->setItemText( cur, Tags[Meta::valAlbum] ); - } - - if( Tags.contains( Meta::valAlbumArtist ) ) - { - cur = ui->kComboBox_albumArtist->currentIndex(); - ui->kComboBox_albumArtist->setItemText( cur, Tags[Meta::valAlbumArtist] ); - } - - if( Tags.contains( Meta::valTrackNr ) ) - ui->qSpinBox_track->setValue( Tags[Meta::valTrackNr].toInt() ); - - if( Tags.contains( Meta::valComment ) ) - ui->qPlainTextEdit_comment->setPlainText( Tags[Meta::valComment] ); - - if( Tags.contains( Meta::valYear ) ) - ui->qSpinBox_year->setValue( Tags[Meta::valYear].toInt() ); - - if( Tags.contains( Meta::valComposer ) ) - { - cur = ui->kComboBox_composer->currentIndex(); - ui->kComboBox_composer->setItemText( cur, Tags[Meta::valComposer] ); - } - - if( Tags.contains( Meta::valGenre ) ) - { - cur = ui->kComboBox_genre->currentIndex(); - ui->kComboBox_genre->setItemText( cur, Tags[Meta::valGenre] ); - } - - if( Tags.contains( Meta::valDiscNr ) ) - { - ui->qSpinBox_discNumber->setValue( Tags[Meta::valDiscNr].toInt() ); - } - } - else - { - debug() << "guessing tags from filename failed" << endl; - } + KDialog *dialog = qobject_cast<KDialog*>(sender()); + Q_ASSERT(dialog); + FilenameLayoutDialog *widget = qobject_cast<FilenameLayoutDialog*>(dialog->mainWidget()); + Q_ASSERT(widget); + + TagGuesser guesser; + guesser.setSchema( widget->getParsableScheme() ); + guesser.setCaseType( widget->getCaseOptions() ); + guesser.setConvertUnderscores( widget->getUnderscoreOptions() ); + guesser.setCutTrailingSpaces( widget->getWhitespaceOptions() ); + + foreach( Meta::TrackPtr t, m_tracks ) { + widget->setFileName( t->playableUrl().path() ); + guesser.setFilename( widget->getParsableFileName() ); + + if( guesser.guess() ) + { + QVariantMap tags = guesser.tags(); + if( t == m_currentTrack ) + setTagsToUi( tags ); + setTagsToTrack(t, tags); + m_changed = true; + } + } } -//creates a KDialog and executes the FilenameLayoutDialog. Grabs a filename scheme, extracts tags (via TagGuesser) from filename and fills the appropriate fields on TagDialog. void TagDialog::guessFromFilename() //SLOT { @@ -496,7 +414,7 @@ TagDialog::guessFromFilename() //SLOT widget->setFileName( m_currentTrack->playableUrl().path() ); dialog->setMainWidget( widget ); connect(dialog, SIGNAL(okClicked()), widget, SLOT(onAccept())); - connect(dialog, SIGNAL(okClicked()), this, SLOT(onFilenameSchemeChanged())); + connect(dialog, SIGNAL(okClicked()), SLOT(filenameSchemeChanged())); dialog->show(); } @@ -774,69 +692,106 @@ TagDialog::setTagsToUi( const QVariantMap &tags ) // -- the rest - ui->kLineEdit_title->setText( tags.value( Meta::Field::TITLE ).toString() ); - selectOrInsertText( tags.value( Meta::Field::ARTIST ).toString(), ui->kComboBox_artist ); - selectOrInsertText( tags.value( Meta::Field::ALBUM ).toString(), ui->kComboBox_album ); - selectOrInsertText( tags.value( Meta::Field::ALBUMARTIST ).toString(), ui->kComboBox_albumArtist ); - selectOrInsertText( tags.value( Meta::Field::COMPOSER ).toString(), ui->kComboBox_composer ); - ui->qPlainTextEdit_comment->setPlainText( tags.value( Meta::Field::COMMENT ).toString() ); - selectOrInsertText( tags.value( Meta::Field::GENRE ).toString(), ui->kComboBox_genre ); - ui->qSpinBox_track->setValue( tags.value( Meta::Field::TRACKNUMBER ).toInt() ); - ui->qSpinBox_discNumber->setValue( tags.value( Meta::Field::DISCNUMBER ).toInt() ); - ui->qSpinBox_year->setValue( tags.value( Meta::Field::YEAR ).toInt() ); - ui->kLineEdit_Bpm->setText( tags.value( Meta::Field::BPM ).toString() ); - - ui->qLabel_length->setText( unknownSafe( Meta::msToPrettyTime( tags.value( Meta::Field::LENGTH ).toLongLong() ) ) ); - ui->qLabel_bitrate->setText( Meta::prettyBitrate( tags.value( Meta::Field::BITRATE ).toInt() ) ); - ui->qLabel_samplerate->setText( unknownSafe( tags.value( Meta::Field::SAMPLERATE ).toInt() ) ); - ui->qLabel_size->setText( Meta::prettyFilesize( tags.value( Meta::Field::FILESIZE ).toLongLong() ) ); - ui->qLabel_format->setText( unknownSafe( tags.value( Meta::Field::TYPE ).toString() ) ); - - ui->qSpinBox_score->setValue( tags.value( Meta::Field::SCORE ).toInt() ); - ui->ratingWidget->setRating( tags.value( Meta::Field::RATING ).toInt() ); - ui->ratingWidget->setMaxRating( 10 ); - ui->qLabel_playcount->setText( unknownSafe( tags.value( Meta::Field::PLAYCOUNT ).toInt() ) ); - - QDate firstPlayed = tags.value( Meta::Field::FIRST_PLAYED ).toDate(); - ui->qLabel_firstPlayed->setText( firstPlayed.isValid() ? + if( tags.contains( Meta::Field::TITLE ) ) + ui->kLineEdit_title->setText( tags.value( Meta::Field::TITLE ).toString() ); + if( tags.contains( Meta::Field::ARTIST) ) + selectOrInsertText( tags.value( Meta::Field::ARTIST ).toString(), ui->kComboBox_artist ); + if( tags.contains( Meta::Field::ALBUM ) ) + selectOrInsertText( tags.value( Meta::Field::ALBUM ).toString(), ui->kComboBox_album ); + if( tags.contains( Meta::Field::ALBUMARTIST) ) + selectOrInsertText( tags.value( Meta::Field::ALBUMARTIST ).toString(), ui->kComboBox_albumArtist ); + if( tags.contains( Meta::Field::COMPOSER ) ) + selectOrInsertText( tags.value( Meta::Field::COMPOSER ).toString(), ui->kComboBox_composer ); + if( tags.contains( Meta::Field::COMMENT ) ) + ui->qPlainTextEdit_comment->setPlainText( tags.value( Meta::Field::COMMENT ).toString() ); + if( tags.contains( Meta::Field::GENRE ) ) + selectOrInsertText( tags.value( Meta::Field::GENRE ).toString(), ui->kComboBox_genre ); + if( tags.contains( Meta::Field::TRACKNUMBER ) ) + ui->qSpinBox_track->setValue( tags.value( Meta::Field::TRACKNUMBER ).toInt() ); + if( tags.contains( Meta::Field::DISCNUMBER ) ) + ui->qSpinBox_discNumber->setValue( tags.value( Meta::Field::DISCNUMBER ).toInt() ); + if( tags.contains( Meta::Field::YEAR ) ) + ui->qSpinBox_year->setValue( tags.value( Meta::Field::YEAR ).toInt() ); + if( tags.contains( Meta::Field::BPM ) ) + ui->kLineEdit_Bpm->setText( tags.value( Meta::Field::BPM ).toString() ); + + if( tags.contains( Meta::Field::LENGTH ) ) + ui->qLabel_length->setText( unknownSafe( Meta::msToPrettyTime( tags.value( Meta::Field::LENGTH ).toLongLong() ) ) ); + if( tags.contains( Meta::Field::BITRATE ) ) + ui->qLabel_bitrate->setText( Meta::prettyBitrate( tags.value( Meta::Field::BITRATE ).toInt() ) ); + if( tags.contains( Meta::Field::SAMPLERATE ) ) + ui->qLabel_samplerate->setText( unknownSafe( tags.value( Meta::Field::SAMPLERATE ).toInt() ) ); + if( tags.contains( Meta::Field::FILESIZE ) ) + ui->qLabel_size->setText( Meta::prettyFilesize( tags.value( Meta::Field::FILESIZE ).toLongLong() ) ); + if( tags.contains( Meta::Field::TYPE ) ) + ui->qLabel_format->setText( unknownSafe( tags.value( Meta::Field::TYPE ).toString() ) ); + + if( tags.contains( Meta::Field::SCORE ) ) + ui->qSpinBox_score->setValue( tags.value( Meta::Field::SCORE ).toInt() ); + if( tags.contains( Meta::Field::RATING ) ) + { + ui->ratingWidget->setRating( tags.value( Meta::Field::RATING ).toInt() ); + ui->ratingWidget->setMaxRating( 10 ); + } + if( tags.contains( Meta::Field::PLAYCOUNT ) ) + ui->qLabel_playcount->setText( unknownSafe( tags.value( Meta::Field::PLAYCOUNT ).toInt() ) ); + + if( tags.contains( Meta::Field::FIRST_PLAYED ) ) + { + QDate firstPlayed = tags.value( Meta::Field::FIRST_PLAYED ).toDate(); + ui->qLabel_firstPlayed->setText( firstPlayed.isValid() ? KGlobal::locale()->formatDate( firstPlayed, KLocale::ShortDate ) : i18nc( "When this track first played", "Never") ); + } - QDate lastPlayed = tags.value( Meta::Field::LAST_PLAYED ).toDate(); - ui->qLabel_lastPlayed->setText( lastPlayed.isValid() ? - KGlobal::locale()->formatDate( lastPlayed, KLocale::ShortDate ) : - i18nc( "When this track was last played", "Never") ); + if( tags.contains( Meta::Field::LAST_PLAYED ) ) + { + QDate lastPlayed = tags.value( Meta::Field::LAST_PLAYED ).toDate(); + ui->qLabel_lastPlayed->setText( lastPlayed.isValid() ? + KGlobal::locale()->formatDate( lastPlayed, KLocale::ShortDate ) : + i18nc( "When this track was last played", "Never") ); + } - ui->qLabel_collection->setText( tags.contains( Meta::Field::COLLECTION ) ? - tags.value( Meta::Field::COLLECTION ).toString() : - i18nc( "The collection this track is part of", "None") ); + if( tags.contains( Meta::Field::COLLECTION ) ) + { + ui->qLabel_collection->setText( tags.contains( Meta::Field::COLLECTION ) ? + tags.value( Meta::Field::COLLECTION ).toString() : + i18nc( "The collection this track is part of", "None") ); + } - ui->kRichTextEdit_lyrics->setTextOrHtml( tags.value( Meta::Field::LYRICS ).toString() ); + if( tags.contains( Meta::Field::LYRICS ) ) + ui->kRichTextEdit_lyrics->setTextOrHtml( tags.value( Meta::Field::LYRICS ).toString() ); - m_labelModel->setLabels( tags.value( Meta::Field::LABELS ).toStringList() ); - ui->labelsList->update(); + if( tags.contains( Meta::Field::LABELS ) ) + { + m_labelModel->setLabels( tags.value( Meta::Field::LABELS ).toStringList() ); + ui->labelsList->update(); + } updateCover(); setControlsAccessability(); // If it's a local file, write the directory to m_path, else disable the "open in konqui" button - QString urlString = tags.value( Meta::Field::URL ).toString(); - KUrl url( urlString ); - //pathOrUrl will give localpath or proper url for remote. - ui->kLineEdit_location->setText( url.pathOrUrl() ); - if( url.isLocalFile() ) + if( tags.contains( Meta::Field::URL ) ) { - ui->locationLabel->show(); - ui->kLineEdit_location->show(); - QFileInfo fi( urlString ); - m_path = fi.isDir() ? urlString : url.directory( KUrl::AppendTrailingSlash ); - ui->pushButton_open->setEnabled( true ); - } - else - { - m_path = QString(); - ui->pushButton_open->setEnabled( false ); + QString urlString = tags.value( Meta::Field::URL ).toString(); + KUrl url( urlString ); + //pathOrUrl will give localpath or proper url for remote. + ui->kLineEdit_location->setText( url.pathOrUrl() ); + if( url.isLocalFile() ) + { + ui->locationLabel->show(); + ui->kLineEdit_location->show(); + QFileInfo fi( urlString ); + m_path = fi.isDir() ? urlString : url.directory( KUrl::AppendTrailingSlash ); + ui->pushButton_open->setEnabled( true ); + } + else + { + m_path = QString(); + ui->pushButton_open->setEnabled( false ); + } } m_changed = oldChanged; @@ -1410,10 +1365,7 @@ TagDialog::musicbrainzTaggerResult( const QMap<Meta::TrackPtr, QVariantMap> resu } m_changed = true; - if( m_perTrack ) - setTagsToUi( m_storedTags.value( m_currentTrack ) ); - else - setTagsToUi( getTagsFromMultipleTracks() ); + setTagsToUi(); } #include "TagDialog.moc" diff --git a/src/dialogs/TagDialog.h b/src/dialogs/TagDialog.h index ff24745..756adc2 100644 --- a/src/dialogs/TagDialog.h +++ b/src/dialogs/TagDialog.h @@ -124,7 +124,7 @@ class AMAROK_EXPORT TagDialog : public KDialog, public Meta::Observer */ void labelSelected(); - void onFilenameSchemeChanged(); + void filenameSchemeChanged(); private: /** Sets some further properties and connects all the signals */ diff --git a/src/dialogs/TagGuesser.cpp b/src/dialogs/TagGuesser.cpp index b1a503f..42f9cae 100644 --- a/src/dialogs/TagGuesser.cpp +++ b/src/dialogs/TagGuesser.cpp @@ -17,6 +17,8 @@ #define DEBUG_PREFIX "TagGuesser" #include "TagGuesser.h" +#include "shared/MetaValues.h" +#include "core/meta/support/MetaConstants.h" #include "core/support/Amarok.h" #include "core/support/Debug.h" @@ -81,7 +83,9 @@ TagGuesser::guess() if( !key ) continue; - m_tags.insert( key, convertTagCaseType( tags[key].toString(), m_caseOptions ) ); + const QVariant &val = tags[key]; + debug() << "Key: " << key << "\nvalue Type: " << val.typeName(); + m_tags.insert( Meta::XesamNameForField(key), val.type() == QVariant::String ? convertTagCaseType( val.toString(), m_caseOptions ) : val ); } m_guessed = !m_tags.isEmpty(); @@ -139,7 +143,7 @@ TagGuesser::coloredFileName() foreach( qint64 key, tags.keys() ) { QString value = tags[key].toString(); - coloredFileName.replace( value, "<font color=\"" + fieldColor( key ) + + coloredFileName.replace( value, "<font color=\"" + fieldColor( Meta::XesamNameForField( key ) ).name() + "\">" + value + "</font>", Qt::CaseInsensitive ); } return coloredFileName; @@ -148,55 +152,19 @@ TagGuesser::coloredFileName() return m_fileName; } -QString -TagGuesser::fieldColor( qint64 field ) +QColor +TagGuesser::fieldColor( const QString &field ) { Qt::GlobalColor color; - switch ( field ) - { - case Meta::valAlbum: - color = album_color; - break; - - case Meta::valAlbumArtist: - color = albumartist_color; - break; - - case Meta::valArtist: - color = artist_color; - break; - - case Meta::valComment: - color = comment_color; - break; - - case Meta::valComposer: - color = composer_color; - break; - - case Meta::valDiscNr: - color = discnr_color; - break; - - case Meta::valGenre: - color = genre_color; - break; - - case Meta::valTitle: - color = title_color; - break; - - case Meta::valTrackNr: - color = track_color; - break; - - case Meta::valYear: - color = year_color; - break; - - default: - color = Qt::black; - } - - return QColor( color ).name(); + if( field == Meta::Field::ALBUM ) return album_color; + if( field == Meta::Field::ALBUMARTIST ) return albumartist_color; + if( field == Meta::Field::ARTIST ) return artist_color; + if( field == Meta::Field::COMMENT ) return comment_color; + if( field == Meta::Field::COMPOSER ) return composer_color; + if( field == Meta::Field::DISCNUMBER ) return discnr_color; + if( field == Meta::Field::GENRE ) return genre_color; + if( field == Meta::Field::TITLE ) return title_color; + if( field == Meta::Field::TRACKNUMBER ) return track_color; + if( field == Meta::Field::YEAR ) return year_color; + return Qt::black; } diff --git a/src/dialogs/TagGuesser.h b/src/dialogs/TagGuesser.h index 432d38f..1ccff3a 100644 --- a/src/dialogs/TagGuesser.h +++ b/src/dialogs/TagGuesser.h @@ -19,6 +19,7 @@ #include <QMap> #include <QString> +#include "shared/MetaValues.h" #define album_color Qt::red #define albumartist_color Qt::blue @@ -75,16 +76,21 @@ class TagGuesser /** * @Returns a list of guessed Tags */ - QMap<qint64,QString> tags() { return m_tags; }; + QVariantMap tags() { return m_tags; }; /** * @Returns a colored version of the filename */ QString coloredFileName(); + /** + * @Returns color name for specified metadata field + */ + QColor fieldColor( const QString &field ); + private: - QMap<qint64,QString> m_tags; //!< Taglist (e.g. < Meta::valArtist,"some artist" > + QVariantMap m_tags; //!< Taglist (e.g. < Meta::Field::ARTIST,"some artist" > bool m_guessed; //!< Is true when guessing was done QString m_fileName; //!< Filename to be guessed from QString m_schema; //!< Schema after which should be guessed @@ -99,11 +105,6 @@ class TagGuesser * @returns the converted tag */ QString convertTagCaseType( const QString &tag, int type ); - - /** - * @Returns color name for specified metadata field - */ - QString fieldColor( qint64 field ); }; #endif /* TAGGUESSER_H */ -- 1.7.11.2
_______________________________________________ Amarok-devel mailing list Amarok-devel@kde.org https://mail.kde.org/mailman/listinfo/amarok-devel