From 98fd82a3718e927730816de27db6225fb453ad37 Mon Sep 17 00:00:00 2001 From: Mattias Andersson Date: Mon, 12 May 2014 23:57:11 +0200 Subject: [PATCH 1/6] Use the TagReaderClient to tag the files in the CD ripper instead of using Taglib directly. --- src/transcoder/transcoder.cpp | 1 - src/transcoder/transcoder.h | 6 +- src/ui/ripcd.cpp | 117 +++++++++++++++------------------- src/ui/ripcd.h | 27 ++++++-- 4 files changed, 77 insertions(+), 74 deletions(-) diff --git a/src/transcoder/transcoder.cpp b/src/transcoder/transcoder.cpp index 5a9696b97..1c2ed0625 100644 --- a/src/transcoder/transcoder.cpp +++ b/src/transcoder/transcoder.cpp @@ -324,7 +324,6 @@ Transcoder::StartJobStatus Transcoder::MaybeStartNextJob() { Job job = queued_jobs_.takeFirst(); if (StartJob(job)) { - emit(JobOutputName(job.output)); return StartedSuccessfully; } diff --git a/src/transcoder/transcoder.h b/src/transcoder/transcoder.h index 61d45f2b8..78e5d015b 100644 --- a/src/transcoder/transcoder.h +++ b/src/transcoder/transcoder.h @@ -70,7 +70,6 @@ signals: void JobComplete(const QString& filename, bool success); void LogLine(const QString& message); void AllJobsComplete(); - void JobOutputName(const QString& filename); protected: bool event(QEvent* e); @@ -125,7 +124,8 @@ signals: StartJobStatus MaybeStartNextJob(); bool StartJob(const Job& job); - GstElement* CreateElement(const QString& factory_name, GstElement* bin = nullptr, + GstElement* CreateElement(const QString& factory_name, + GstElement* bin = nullptr, const QString& name = QString()); GstElement* CreateElementForMimeType(const QString& element_type, const QString& mime_type, @@ -138,7 +138,7 @@ signals: gpointer data); private: - typedef QList > JobStateList; + typedef QList> JobStateList; int max_threads_; QList queued_jobs_; diff --git a/src/ui/ripcd.cpp b/src/ui/ripcd.cpp index f3b7d4a0b..3f7dcce59 100644 --- a/src/ui/ripcd.cpp +++ b/src/ui/ripcd.cpp @@ -22,6 +22,8 @@ #include "transcoder/transcoderoptionsdialog.h" #include "ui/iconloader.h" #include "core/logging.h" +#include "core/song.h" +#include "core/tagreaderclient.h" #include "core/utilities.h" #include @@ -35,14 +37,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include // winspool.h defines this :( #ifdef AddJob @@ -108,8 +102,6 @@ RipCD::RipCD(QWidget* parent) connect(transcoder_, SIGNAL(JobComplete(QString, bool)), SLOT(JobComplete(QString, bool))); connect(transcoder_, SIGNAL(AllJobsComplete()), SLOT(AllJobsComplete())); - connect(transcoder_, SIGNAL(JobOutputName(QString)), - SLOT(AppendOutput(QString))); connect(this, SIGNAL(RippingComplete()), SLOT(ThreadedTranscoding())); connect(this, SIGNAL(SignalUpdateProgress()), SLOT(UpdateProgress())); @@ -213,20 +205,15 @@ void RipCD::ThreadClickedRipButton() { // Set up progress bar emit(SignalUpdateProgress()); - tracks_to_rip_.clear(); - for (int i = 1; i <= i_tracks_; i++) { - if (!checkboxes_.value(i - 1)->isChecked()) { - continue; - } - tracks_to_rip_.append(i); - QString filename = temporary_directory_ + - ParseFileFormatString(ui_->format_filename->text(), i) + - ".wav"; + + for (const TrackInformation& track : tracks_) { + QString filename = + QString("%1%2.wav").arg(temporary_directory_).arg(track.track_number); QFile* destination_file = new QFile(filename); destination_file->open(QIODevice::WriteOnly); - lsn_t i_first_lsn = cdio_get_track_lsn(cdio_, i); - lsn_t i_last_lsn = cdio_get_track_last_lsn(cdio_, i); + lsn_t i_first_lsn = cdio_get_track_lsn(cdio_, track.track_number); + lsn_t i_last_lsn = cdio_get_track_last_lsn(cdio_, track.track_number); WriteWAVHeader(destination_file, (i_last_lsn - i_first_lsn + 1) * CDIO_CD_FRAMESIZE_RAW); @@ -253,29 +240,18 @@ void RipCD::ThreadClickedRipButton() { TranscoderPreset preset = ui_->format->itemData(ui_->format->currentIndex()) .value(); - QString outfilename = GetOutputFileName(filename, preset); - transcoder_->AddJob(filename, preset, outfilename); + transcoder_->AddJob(filename, preset, track.transcoded_filename); } emit(RippingComplete()); } -// Returns the rightmost non-empty part of 'path'. -QString RipCD::TrimPath(const QString& path) const { - return path.section('/', -1, -1, QString::SectionSkipEmpty); -} - -QString RipCD::GetOutputFileName(const QString& input, - const TranscoderPreset& preset) const { +QString RipCD::GetOutputFileName(const QString& basename) const { QString path = ui_->destination->itemData(ui_->destination->currentIndex()).toString(); - if (path.isEmpty()) { - // Keep the original path. - return input.section('.', 0, -2) + '.' + preset.extension_; - } else { - QString file_name = TrimPath(input); - file_name = file_name.section('.', 0, -2); - return path + '/' + file_name + '.' + preset.extension_; - } + QString extension = ui_->format->itemData(ui_->format->currentIndex()) + .value() + .extension_; + return path + '/' + basename + '.' + extension; } QString RipCD::ParseFileFormatString(const QString& file_format, @@ -323,6 +299,20 @@ void RipCD::ClickedRipButton() { } return; } + + // Add tracks to the rip list. + tracks_.clear(); + for (int i = 1; i <= i_tracks_; ++i) { + if (!checkboxes_.value(i - 1)->isChecked()) { + continue; + } + QString transcoded_filename = GetOutputFileName( + ParseFileFormatString(ui_->format_filename->text(), i)); + QString title = track_names_.value(i - 1)->text(); + AddTrack(i, title, transcoded_filename); + } + + // Start ripping. SetWorking(true); { QMutexLocker l(&mutex_); @@ -331,6 +321,12 @@ void RipCD::ClickedRipButton() { QtConcurrent::run(this, &RipCD::ThreadClickedRipButton); } +void RipCD::AddTrack(int track_number, const QString& title, + const QString& transcoded_filename) { + TrackInformation track(track_number, title, transcoded_filename); + tracks_.append(track); +} + void RipCD::JobComplete(const QString& filename, bool success) { (*(success ? &finished_success_ : &finished_failed_))++; emit(SignalUpdateProgress()); @@ -338,35 +334,28 @@ void RipCD::JobComplete(const QString& filename, bool success) { void RipCD::AllJobsComplete() { RemoveTemporaryDirectory(); - - // having a little trouble on wav files, works fine on ogg-vorbis - qSort(generated_files_); - - for (int i = 0; i < generated_files_.length(); i++) { - TagLib::FileRef f(generated_files_.value(i).toUtf8().constData()); - - f.tag()->setTitle(track_names_.value(tracks_to_rip_.value(i) - 1) - ->text() - .toUtf8() - .constData()); - f.tag()->setAlbum(ui_->albumLineEdit->text().toUtf8().constData()); - f.tag()->setArtist(ui_->artistLineEdit->text().toUtf8().constData()); - f.tag()->setGenre(ui_->genreLineEdit->text().toUtf8().constData()); - f.tag()->setYear(ui_->yearLineEdit->text().toInt()); - f.tag()->setTrack(tracks_to_rip_.value(i) - 1); - // Need to check this - // f.tag()->setDisc(ui_->discLineEdit->text().toInt()); - f.save(); - } - // Resets lists - generated_files_.clear(); - tracks_to_rip_.clear(); - + TagFiles(); SetWorking(false); } -void RipCD::AppendOutput(const QString& filename) { - generated_files_.append(filename); +void RipCD::TagFiles() { + TranscoderPreset preset = ui_->format->itemData(ui_->format->currentIndex()) + .value(); + for (const TrackInformation& track : tracks_) { + Song song; + song.InitFromFilePartial(track.transcoded_filename); + song.set_title(track.title); + song.set_album(ui_->albumLineEdit->text()); + song.set_artist(ui_->artistLineEdit->text()); + song.set_genre(ui_->genreLineEdit->text()); + song.set_year(ui_->yearLineEdit->text().toInt()); + song.set_track(track.track_number); + song.set_disc(ui_->discLineEdit->text().toInt()); + song.set_filetype(preset.type_); + + TagReaderClient::Instance()->SaveFileBlocking(song.url().toLocalFile(), + song); + } } void RipCD::Options() { diff --git a/src/ui/ripcd.h b/src/ui/ripcd.h index 9b1a98cad..228540881 100644 --- a/src/ui/ripcd.h +++ b/src/ui/ripcd.h @@ -44,6 +44,18 @@ class RipCD : public QDialog { void showEvent(QShowEvent* event); private: + struct TrackInformation { + TrackInformation(int track_number, const QString& title, + const QString& transcoded_filename) + : track_number(track_number), + title(title), + transcoded_filename(transcoded_filename) {} + + int track_number; + QString title; + QString transcoded_filename; + }; + static const char* kSettingsGroup; static const int kProgressInterval; static const int kMaxDestinationItems; @@ -55,9 +67,8 @@ class RipCD : public QDialog { std::unique_ptr ui_; CdIo_t* cdio_; QList checkboxes_; - QList generated_files_; - QList tracks_to_rip_; QList track_names_; + QList tracks_; QString last_add_dir_; QPushButton* cancel_button_; QPushButton* close_button_; @@ -68,14 +79,19 @@ class RipCD : public QDialog { void WriteWAVHeader(QFile* stream, int32_t i_bytecount); int NumTracksToRip(); + void AddTrack(int track_number, const QString& title, + const QString& transcoded_filename); void ThreadClickedRipButton(); - QString TrimPath(const QString& path) const; - QString GetOutputFileName(const QString& input, - const TranscoderPreset& preset) const; + // Constructs a filename from the given base name with a path taken + // from the ui dialog and an extension that corresponds to the audio + // format chosen in the ui. + QString GetOutputFileName(const QString& basename) const; + QString ParseFileFormatString(const QString& file_format, int track_no) const; void SetWorking(bool working); void AddDestinationDirectory(QString dir); void RemoveTemporaryDirectory(); + void TagFiles(); signals: void RippingComplete(); @@ -86,7 +102,6 @@ signals: void ClickedRipButton(); void JobComplete(const QString& filename, bool success); void AllJobsComplete(); - void AppendOutput(const QString& filename); void Options(); void AddDestination(); void Cancel(); From 467a1443e45b90de5f449d0a202b0c8e3e9eee2e Mon Sep 17 00:00:00 2001 From: Mattias Andersson Date: Mon, 12 May 2014 23:58:51 +0200 Subject: [PATCH 2/6] Capture log messages from the transcoder. --- src/ui/ripcd.cpp | 3 +++ src/ui/ripcd.h | 1 + 2 files changed, 4 insertions(+) diff --git a/src/ui/ripcd.cpp b/src/ui/ripcd.cpp index 3f7dcce59..8bbc545e2 100644 --- a/src/ui/ripcd.cpp +++ b/src/ui/ripcd.cpp @@ -102,6 +102,7 @@ RipCD::RipCD(QWidget* parent) connect(transcoder_, SIGNAL(JobComplete(QString, bool)), SLOT(JobComplete(QString, bool))); connect(transcoder_, SIGNAL(AllJobsComplete()), SLOT(AllJobsComplete())); + connect(transcoder_, SIGNAL(LogLine(QString)), SLOT(LogLine(QString))); connect(this, SIGNAL(RippingComplete()), SLOT(ThreadedTranscoding())); connect(this, SIGNAL(SignalUpdateProgress()), SLOT(UpdateProgress())); @@ -480,4 +481,6 @@ void RipCD::BuildTrackListTable() { } } +void RipCD::LogLine(const QString& message) { qLog(Debug) << message; } + void RipCD::showEvent(QShowEvent* event) { BuildTrackListTable(); } diff --git a/src/ui/ripcd.h b/src/ui/ripcd.h index 228540881..7fda25054 100644 --- a/src/ui/ripcd.h +++ b/src/ui/ripcd.h @@ -108,6 +108,7 @@ signals: void SelectAll(); void SelectNone(); void InvertSelection(); + void LogLine(const QString& message); }; #endif // SRC_UI_RIPCD_H_ From 182c90ccf45d3855a885df5cf7a240b54379d4db Mon Sep 17 00:00:00 2001 From: Mattias Andersson Date: Tue, 13 May 2014 15:18:42 +0200 Subject: [PATCH 3/6] Run RipCD::TagFiles in a background thread. --- src/ui/ripcd.cpp | 30 ++++++++++++++++++------------ src/ui/ripcd.h | 26 ++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/ui/ripcd.cpp b/src/ui/ripcd.cpp index 8bbc545e2..769df1a93 100644 --- a/src/ui/ripcd.cpp +++ b/src/ui/ripcd.cpp @@ -22,7 +22,6 @@ #include "transcoder/transcoderoptionsdialog.h" #include "ui/iconloader.h" #include "core/logging.h" -#include "core/song.h" #include "core/tagreaderclient.h" #include "core/utilities.h" @@ -335,25 +334,32 @@ void RipCD::JobComplete(const QString& filename, bool success) { void RipCD::AllJobsComplete() { RemoveTemporaryDirectory(); - TagFiles(); + // Save tags in the background. + TranscoderPreset preset = ui_->format->itemData(ui_->format->currentIndex()) + .value(); + AlbumInformation album( + ui_->albumLineEdit->text(), ui_->artistLineEdit->text(), + ui_->genreLineEdit->text(), ui_->yearLineEdit->text().toInt(), + ui_->discLineEdit->text().toInt(), preset.type_); + QtConcurrent::run(this, &RipCD::TagFiles, album, tracks_); SetWorking(false); } -void RipCD::TagFiles() { - TranscoderPreset preset = ui_->format->itemData(ui_->format->currentIndex()) - .value(); +void RipCD::TagFiles(const AlbumInformation& album, + const QList& tracks) { for (const TrackInformation& track : tracks_) { Song song; song.InitFromFilePartial(track.transcoded_filename); - song.set_title(track.title); - song.set_album(ui_->albumLineEdit->text()); - song.set_artist(ui_->artistLineEdit->text()); - song.set_genre(ui_->genreLineEdit->text()); - song.set_year(ui_->yearLineEdit->text().toInt()); song.set_track(track.track_number); - song.set_disc(ui_->discLineEdit->text().toInt()); - song.set_filetype(preset.type_); + song.set_title(track.title); + song.set_album(album.album); + song.set_artist(album.artist); + song.set_genre(album.genre); + song.set_year(album.year); + song.set_disc(album.disc); + song.set_filetype(album.type); + Q_ASSERT(QThread::currentThread() != qApp->thread()); TagReaderClient::Instance()->SaveFileBlocking(song.url().toLocalFile(), song); } diff --git a/src/ui/ripcd.h b/src/ui/ripcd.h index 7fda25054..f045a51b5 100644 --- a/src/ui/ripcd.h +++ b/src/ui/ripcd.h @@ -24,6 +24,7 @@ #include #include #include +#include "core/song.h" #include "ui_ripcd.h" #include class Ui_RipCD; @@ -56,6 +57,25 @@ class RipCD : public QDialog { QString transcoded_filename; }; + struct AlbumInformation { + AlbumInformation(const QString& album, const QString& artist, + const QString& genre, int year, int disc, + Song::FileType type) + : album(album), + artist(artist), + genre(genre), + year(year), + disc(disc), + type(type) {} + + QString album; + QString artist; + QString genre; + int year; + int disc; + Song::FileType type; + }; + static const char* kSettingsGroup; static const int kProgressInterval; static const int kMaxDestinationItems; @@ -86,16 +106,18 @@ class RipCD : public QDialog { // from the ui dialog and an extension that corresponds to the audio // format chosen in the ui. QString GetOutputFileName(const QString& basename) const; - QString ParseFileFormatString(const QString& file_format, int track_no) const; void SetWorking(bool working); void AddDestinationDirectory(QString dir); void RemoveTemporaryDirectory(); - void TagFiles(); + // Tags the final files. This function should not be run in the UI thread. + void TagFiles(const AlbumInformation& album, + const QList& tracks); signals: void RippingComplete(); void SignalUpdateProgress(); + private slots: void UpdateProgress(); void ThreadedTranscoding(); From 2137ac4709a1b482f67e41262d49df82e41e1a4f Mon Sep 17 00:00:00 2001 From: Mattias Andersson Date: Sun, 18 May 2014 14:15:06 +0200 Subject: [PATCH 4/6] Keep working until tagging is complete. --- src/ui/ripcd.cpp | 19 +++++++++++++++++-- src/ui/ripcd.h | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/ui/ripcd.cpp b/src/ui/ripcd.cpp index 769df1a93..509bf3449 100644 --- a/src/ui/ripcd.cpp +++ b/src/ui/ripcd.cpp @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include #include @@ -334,6 +336,7 @@ void RipCD::JobComplete(const QString& filename, bool success) { void RipCD::AllJobsComplete() { RemoveTemporaryDirectory(); + // Save tags in the background. TranscoderPreset preset = ui_->format->itemData(ui_->format->currentIndex()) .value(); @@ -341,8 +344,11 @@ void RipCD::AllJobsComplete() { ui_->albumLineEdit->text(), ui_->artistLineEdit->text(), ui_->genreLineEdit->text(), ui_->yearLineEdit->text().toInt(), ui_->discLineEdit->text().toInt(), preset.type_); - QtConcurrent::run(this, &RipCD::TagFiles, album, tracks_); - SetWorking(false); + QFuture future = + QtConcurrent::run(this, &RipCD::TagFiles, album, tracks_); + QFutureWatcher* watcher = new QFutureWatcher(this); + connect(watcher, SIGNAL(finished()), SLOT(TaggingComplete())); + watcher->setFuture(future); } void RipCD::TagFiles(const AlbumInformation& album, @@ -365,6 +371,15 @@ void RipCD::TagFiles(const AlbumInformation& album, } } +void RipCD::TaggingComplete() { + QFutureWatcher* watcher = dynamic_cast*>(sender()); + if (!watcher) return; + watcher->deleteLater(); + + SetWorking(false); + qLog(Debug) << "CD ripper finished."; +} + void RipCD::Options() { TranscoderPreset preset = ui_->format->itemData(ui_->format->currentIndex()) .value(); diff --git a/src/ui/ripcd.h b/src/ui/ripcd.h index f045a51b5..a99ba1ada 100644 --- a/src/ui/ripcd.h +++ b/src/ui/ripcd.h @@ -124,6 +124,7 @@ signals: void ClickedRipButton(); void JobComplete(const QString& filename, bool success); void AllJobsComplete(); + void TaggingComplete(); void Options(); void AddDestination(); void Cancel(); From 7d4343a826299cae59ff25c0ccba7289cac2bcfa Mon Sep 17 00:00:00 2001 From: Mattias Andersson Date: Sun, 18 May 2014 14:39:21 +0200 Subject: [PATCH 5/6] Give functions a more verbose name. --- src/ui/ripcd.cpp | 9 +++++---- src/ui/ripcd.h | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ui/ripcd.cpp b/src/ui/ripcd.cpp index 509bf3449..2c5b9f576 100644 --- a/src/ui/ripcd.cpp +++ b/src/ui/ripcd.cpp @@ -101,8 +101,9 @@ RipCD::RipCD(QWidget* parent) connect(close_button_, SIGNAL(clicked()), SLOT(hide())); connect(transcoder_, SIGNAL(JobComplete(QString, bool)), - SLOT(JobComplete(QString, bool))); - connect(transcoder_, SIGNAL(AllJobsComplete()), SLOT(AllJobsComplete())); + SLOT(TranscodingJobComplete(QString, bool))); + connect(transcoder_, SIGNAL(AllJobsComplete()), + SLOT(AllTranscodingJobsComplete())); connect(transcoder_, SIGNAL(LogLine(QString)), SLOT(LogLine(QString))); connect(this, SIGNAL(RippingComplete()), SLOT(ThreadedTranscoding())); connect(this, SIGNAL(SignalUpdateProgress()), SLOT(UpdateProgress())); @@ -329,12 +330,12 @@ void RipCD::AddTrack(int track_number, const QString& title, tracks_.append(track); } -void RipCD::JobComplete(const QString& filename, bool success) { +void RipCD::TranscodingJobComplete(const QString& filename, bool success) { (*(success ? &finished_success_ : &finished_failed_))++; emit(SignalUpdateProgress()); } -void RipCD::AllJobsComplete() { +void RipCD::AllTranscodingJobsComplete() { RemoveTemporaryDirectory(); // Save tags in the background. diff --git a/src/ui/ripcd.h b/src/ui/ripcd.h index a99ba1ada..bf9f2f39c 100644 --- a/src/ui/ripcd.h +++ b/src/ui/ripcd.h @@ -122,8 +122,8 @@ signals: void UpdateProgress(); void ThreadedTranscoding(); void ClickedRipButton(); - void JobComplete(const QString& filename, bool success); - void AllJobsComplete(); + void TranscodingJobComplete(const QString& filename, bool success); + void AllTranscodingJobsComplete(); void TaggingComplete(); void Options(); void AddDestination(); From 8bb19f1887c296a005c5ca43eb9d451a6e56f4a4 Mon Sep 17 00:00:00 2001 From: Mattias Andersson Date: Wed, 21 May 2014 16:36:46 +0200 Subject: [PATCH 6/6] Save tags using async calls. --- src/ui/ripcd.cpp | 39 +++++++++++++++++++++------------------ src/ui/ripcd.h | 6 ++++-- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/ui/ripcd.cpp b/src/ui/ripcd.cpp index 2c5b9f576..9531be831 100644 --- a/src/ui/ripcd.cpp +++ b/src/ui/ripcd.cpp @@ -21,6 +21,7 @@ #include "transcoder/transcoder.h" #include "transcoder/transcoderoptionsdialog.h" #include "ui/iconloader.h" +#include "core/closure.h" #include "core/logging.h" #include "core/tagreaderclient.h" #include "core/utilities.h" @@ -30,8 +31,6 @@ #include #include #include -#include -#include #include #include #include @@ -69,7 +68,8 @@ RipCD::RipCD(QWidget* parent) finished_success_(0), finished_failed_(0), ui_(new Ui_RipCD), - cancel_requested_(false) { + cancel_requested_(false), + files_tagged_(0) { cdio_ = cdio_open(NULL, DRIVER_UNKNOWN); // Init ui_->setupUi(this); @@ -338,22 +338,19 @@ void RipCD::TranscodingJobComplete(const QString& filename, bool success) { void RipCD::AllTranscodingJobsComplete() { RemoveTemporaryDirectory(); - // Save tags in the background. + // Save tags. TranscoderPreset preset = ui_->format->itemData(ui_->format->currentIndex()) .value(); AlbumInformation album( ui_->albumLineEdit->text(), ui_->artistLineEdit->text(), ui_->genreLineEdit->text(), ui_->yearLineEdit->text().toInt(), ui_->discLineEdit->text().toInt(), preset.type_); - QFuture future = - QtConcurrent::run(this, &RipCD::TagFiles, album, tracks_); - QFutureWatcher* watcher = new QFutureWatcher(this); - connect(watcher, SIGNAL(finished()), SLOT(TaggingComplete())); - watcher->setFuture(future); + TagFiles(album, tracks_); } void RipCD::TagFiles(const AlbumInformation& album, const QList& tracks) { + files_tagged_ = 0; for (const TrackInformation& track : tracks_) { Song song; song.InitFromFilePartial(track.transcoded_filename); @@ -366,19 +363,25 @@ void RipCD::TagFiles(const AlbumInformation& album, song.set_disc(album.disc); song.set_filetype(album.type); - Q_ASSERT(QThread::currentThread() != qApp->thread()); - TagReaderClient::Instance()->SaveFileBlocking(song.url().toLocalFile(), - song); + TagReaderReply* reply = + TagReaderClient::Instance()->SaveFile(song.url().toLocalFile(), song); + NewClosure(reply, SIGNAL(Finished(bool)), this, + SLOT(FileTagged(TagReaderReply*)), reply); } } -void RipCD::TaggingComplete() { - QFutureWatcher* watcher = dynamic_cast*>(sender()); - if (!watcher) return; - watcher->deleteLater(); +void RipCD::FileTagged(TagReaderReply* reply) { + files_tagged_++; + qLog(Debug) << "Tagged" << files_tagged_ << "of" << tracks_.length() + << "files"; - SetWorking(false); - qLog(Debug) << "CD ripper finished."; + // Stop working if all files are tagged. + if (files_tagged_ == tracks_.length()) { + qLog(Debug) << "CD ripper finished."; + SetWorking(false); + } + + reply->deleteLater(); } void RipCD::Options() { diff --git a/src/ui/ripcd.h b/src/ui/ripcd.h index bf9f2f39c..d919c54a9 100644 --- a/src/ui/ripcd.h +++ b/src/ui/ripcd.h @@ -25,8 +25,10 @@ #include #include #include "core/song.h" +#include "core/tagreaderclient.h" #include "ui_ripcd.h" #include + class Ui_RipCD; class Transcoder; @@ -96,6 +98,7 @@ class RipCD : public QDialog { QString temporary_directory_; bool cancel_requested_; QMutex mutex_; + int files_tagged_; void WriteWAVHeader(QFile* stream, int32_t i_bytecount); int NumTracksToRip(); @@ -110,7 +113,6 @@ class RipCD : public QDialog { void SetWorking(bool working); void AddDestinationDirectory(QString dir); void RemoveTemporaryDirectory(); - // Tags the final files. This function should not be run in the UI thread. void TagFiles(const AlbumInformation& album, const QList& tracks); @@ -124,7 +126,7 @@ signals: void ClickedRipButton(); void TranscodingJobComplete(const QString& filename, bool success); void AllTranscodingJobsComplete(); - void TaggingComplete(); + void FileTagged(TagReaderReply* reply); void Options(); void AddDestination(); void Cancel();