diff options
author | Uwe Klotz <uklotz@mixxx.org> | 2019-12-09 19:18:11 +0100 |
---|---|---|
committer | Uwe Klotz <uklotz@mixxx.org> | 2019-12-09 19:31:49 +0100 |
commit | 2eef91c1abf8410d399165310546e9da1a1e7b7d (patch) | |
tree | 333d1a287955e1c683ec35542afa432dc3aa7f5a /src/library | |
parent | f10b7657a3060cb650bbc69788c59446c5e9e629 (diff) | |
parent | da2e78f0ca716b44ffb0e373a59300c213e4033e (diff) |
Merge branch 'master' of git@github.com:mixxxdj/mixxx.git into library-autodj-fixes
# Conflicts:
# src/library/baseplaylistfeature.cpp
# src/library/baseplaylistfeature.h
# src/widget/wtracktableview.cpp
Diffstat (limited to 'src/library')
83 files changed, 1708 insertions, 1240 deletions
diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp index 9ff6e0fcaf..0a4a7bfb23 100644 --- a/src/library/analysisfeature.cpp +++ b/src/library/analysisfeature.cpp @@ -16,15 +16,23 @@ #include "sources/soundsourceproxy.h" #include "util/dnd.h" #include "util/debug.h" - -const QString AnalysisFeature::m_sAnalysisViewName = QString("Analysis"); +#include "util/logger.h" namespace { +const mixxx::Logger kLogger("AnalysisFeature"); + +const QString kViewName = QStringLiteral("Analysis"); + // Utilize all available cores for batch analysis of tracks const int kNumberOfAnalyzerThreads = math_max(1, QThread::idealThreadCount()); inline +int numberOfAnalyzerThreads() { + return kNumberOfAnalyzerThreads; +} + +inline AnalyzerModeFlags getAnalyzerModeFlags( const UserSettingsPointer& pConfig) { // Always enable at least BPM detection for batch analysis, even if disabled @@ -42,50 +50,34 @@ AnalyzerModeFlags getAnalyzerModeFlags( } // anonymous namespace AnalysisFeature::AnalysisFeature( - Library* parent, + Library* pLibrary, UserSettingsPointer pConfig) - : LibraryFeature(parent), - m_library(parent), - m_pConfig(pConfig), + : LibraryFeature(pLibrary, pConfig), + m_baseTitle(tr("Analyze")), + m_icon(":/images/library/ic_library_prepare.svg"), m_pTrackAnalysisScheduler(TrackAnalysisScheduler::NullPointer()), - m_analysisTitleName(tr("Analyze")), m_pAnalysisView(nullptr), - m_icon(":/images/library/ic_library_prepare.svg") { - setTitleDefault(); + m_title(m_baseTitle) { } -void AnalysisFeature::stop() { - if (m_pTrackAnalysisScheduler) { - m_pTrackAnalysisScheduler->stop(); - } -} - -void AnalysisFeature::setTitleDefault() { - m_Title = m_analysisTitleName; - emit(featureIsLoading(this, false)); +void AnalysisFeature::resetTitle() { + m_title = m_baseTitle; + emit featureIsLoading(this, false); } void AnalysisFeature::setTitleProgress(int currentTrackNumber, int totalTracksCount) { - m_Title = QString("%1 (%2 / %3)") - .arg(m_analysisTitleName) + m_title = QString("%1 (%2 / %3)") + .arg(m_baseTitle) .arg(QString::number(currentTrackNumber)) .arg(QString::number(totalTracksCount)); - emit(featureIsLoading(this, false)); -} - -QVariant AnalysisFeature::title() { - return m_Title; -} - -QIcon AnalysisFeature::getIcon() { - return m_icon; + emit featureIsLoading(this, false); } void AnalysisFeature::bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* keyboard) { m_pAnalysisView = new DlgAnalysis(libraryWidget, m_pConfig, - m_library); + m_pLibrary); connect(m_pAnalysisView, &DlgAnalysis::loadTrack, this, @@ -120,7 +112,7 @@ void AnalysisFeature::bindLibraryWidget(WLibrary* libraryWidget, // Let the DlgAnalysis know whether or not analysis is active. emit(analysisActive(static_cast<bool>(m_pTrackAnalysisScheduler))); - libraryWidget->registerView(m_sAnalysisViewName, m_pAnalysisView); + libraryWidget->registerView(kViewName, m_pAnalysisView); } TreeItemModel* AnalysisFeature::getChildModel() { @@ -135,36 +127,73 @@ void AnalysisFeature::refreshLibraryModels() { void AnalysisFeature::activate() { //qDebug() << "AnalysisFeature::activate()"; - emit(switchToView(m_sAnalysisViewName)); + emit switchToView(kViewName); if (m_pAnalysisView) { - emit(restoreSearch(m_pAnalysisView->currentSearch())); + emit restoreSearch(m_pAnalysisView->currentSearch()); } - emit(enableCoverArtDisplay(true)); + emit enableCoverArtDisplay(true); } void AnalysisFeature::analyzeTracks(QList<TrackId> trackIds) { if (!m_pTrackAnalysisScheduler) { + const int numAnalyzerThreads = numberOfAnalyzerThreads(); + kLogger.info() + << "Starting analysis using" + << numAnalyzerThreads + << "analyzer threads"; m_pTrackAnalysisScheduler = TrackAnalysisScheduler::createInstance( - m_library, - kNumberOfAnalyzerThreads, + m_pLibrary, + numAnalyzerThreads, m_pConfig, getAnalyzerModeFlags(m_pConfig)); - connect(m_pTrackAnalysisScheduler.get(), &TrackAnalysisScheduler::progress, - m_pAnalysisView, &DlgAnalysis::onTrackAnalysisSchedulerProgress); - connect(m_pTrackAnalysisScheduler.get(), &TrackAnalysisScheduler::finished, - m_pAnalysisView, &DlgAnalysis::onTrackAnalysisSchedulerFinished); - connect(m_pTrackAnalysisScheduler.get(), &TrackAnalysisScheduler::progress, - this, &AnalysisFeature::onTrackAnalysisSchedulerProgress); - connect(m_pTrackAnalysisScheduler.get(), &TrackAnalysisScheduler::finished, - this, &AnalysisFeature::stopAnalysis); - - emit(analysisActive(true)); + connect(m_pTrackAnalysisScheduler.get(), + &TrackAnalysisScheduler::progress, + m_pAnalysisView, + &DlgAnalysis::onTrackAnalysisSchedulerProgress); + connect(m_pTrackAnalysisScheduler.get(), + &TrackAnalysisScheduler::finished, + m_pAnalysisView, + &DlgAnalysis::onTrackAnalysisSchedulerFinished); + connect(m_pTrackAnalysisScheduler.get(), + &TrackAnalysisScheduler::progress, + this, + &AnalysisFeature::onTrackAnalysisSchedulerProgress); + connect(m_pTrackAnalysisScheduler.get(), + &TrackAnalysisScheduler::finished, + this, + &AnalysisFeature::onTrackAnalysisSchedulerFinished); + + emit analysisActive(true); } if (m_pTrackAnalysisScheduler->scheduleTracksById(trackIds) > 0) { - m_pTrackAnalysisScheduler->resume(); + resumeAnalysis(); + } +} + +void AnalysisFeature::suspendAnalysis() { + if (!m_pTrackAnalysisScheduler) { + return; // inactive + } + kLogger.info() << "Suspending analysis"; + m_pTrackAnalysisScheduler->suspend(); +} + +void AnalysisFeature::resumeAnalysis() { + if (!m_pTrackAnalysisScheduler) { + return; // inactive } + kLogger.info() << "Resuming analysis"; + m_pTrackAnalysisScheduler->resume(); +} + +void AnalysisFeature::stopAnalysis() { + if (!m_pTrackAnalysisScheduler) { + return; // inactive + } + kLogger.info() << "Stopping analysis"; + m_pTrackAnalysisScheduler->stop(); } void AnalysisFeature::onTrackAnalysisSchedulerProgress( @@ -173,31 +202,21 @@ void AnalysisFeature::onTrackAnalysisSchedulerProgress( int totalTracksCount) { // Ignore any delayed progress updates after the analysis // has already been stopped. - if (m_pTrackAnalysisScheduler) { - if (totalTracksCount > 0) { - setTitleProgress(currentTrackNumber, totalTracksCount); - } else { - setTitleDefault(); - } + if (!m_pTrackAnalysisScheduler) { + return; // inactive } -} - -void AnalysisFeature::suspendAnalysis() { - //qDebug() << this << "suspendAnalysis"; - if (m_pTrackAnalysisScheduler) { - m_pTrackAnalysisScheduler->suspend(); + if (totalTracksCount > 0) { + setTitleProgress(currentTrackNumber, totalTracksCount); + } else { + resetTitle(); } } -void AnalysisFeature::resumeAnalysis() { - //qDebug() << this << "resumeAnalysis"; - if (m_pTrackAnalysisScheduler) { - m_pTrackAnalysisScheduler->resume(); +void AnalysisFeature::onTrackAnalysisSchedulerFinished() { + if (!m_pTrackAnalysisScheduler) { + return; // already inactive } -} - -void AnalysisFeature::stopAnalysis() { - //qDebug() << this << "stopAnalysis()"; + kLogger.info() << "Finishing analysis"; if (m_pTrackAnalysisScheduler) { // Free resources by abandoning the queue after the batch analysis // has completed. Batch analysis are not started very frequently @@ -206,12 +225,12 @@ void AnalysisFeature::stopAnalysis() { // for creating the queue with its worker threads are acceptable. m_pTrackAnalysisScheduler.reset(); } - setTitleDefault(); - emit(analysisActive(false)); + resetTitle(); + emit analysisActive(false); } bool AnalysisFeature::dropAccept(QList<QUrl> urls, QObject* pSource) { - QList<TrackId> trackIds = m_library->trackCollection().resolveTrackIdsFromUrls(urls, + QList<TrackId> trackIds = m_pLibrary->trackCollection().resolveTrackIdsFromUrls(urls, !pSource); analyzeTracks(trackIds); return trackIds.size() > 0; diff --git a/src/library/analysisfeature.h b/src/library/analysisfeature.h index f49459af3a..50587b046e 100644 --- a/src/library/analysisfeature.h +++ b/src/library/analysisfeature.h @@ -18,20 +18,22 @@ #include "analyzer/trackanalysisscheduler.h" #include "preferences/usersettings.h" -class Library; class TrackCollection; class AnalysisFeature : public LibraryFeature { Q_OBJECT public: - AnalysisFeature(Library* parent, + AnalysisFeature(Library* pLibrary, UserSettingsPointer pConfig); ~AnalysisFeature() override = default; - void stop(); + QVariant title() override { + return m_title; + } - QVariant title() override; - QIcon getIcon() override; + QIcon getIcon() override { + return m_icon; + } bool dropAccept(QList<QUrl> urls, QObject* pSource) override; bool dragMoveAccept(QUrl url) override; @@ -50,33 +52,32 @@ class AnalysisFeature : public LibraryFeature { void suspendAnalysis(); void resumeAnalysis(); + void stopAnalysis(); private slots: void onTrackAnalysisSchedulerProgress(AnalyzerProgress currentTrackProgress, int currentTrackNumber, int totalTracksCount); - void stopAnalysis(); + void onTrackAnalysisSchedulerFinished(); private: // Sets the title of this feature to the default name, given by // m_sAnalysisTitleName - void setTitleDefault(); + void resetTitle(); // Sets the title of this feature to the default name followed by (x / y) // where x is the current track being analyzed and y is the total number of // tracks in the job void setTitleProgress(int currentTrackNumber, int totalTracksCount); - Library* m_library; + const QString m_baseTitle; + const QIcon m_icon; - UserSettingsPointer m_pConfig; TrackAnalysisScheduler::Pointer m_pTrackAnalysisScheduler; - // The title returned by title() - QVariant m_Title; TreeItemModel m_childModel; - const static QString m_sAnalysisViewName; - QString m_analysisTitleName; DlgAnalysis* m_pAnalysisView; - QIcon m_icon; + + // The title is dynamic and reflects the current progress + QString m_title; }; diff --git a/src/library/analysislibrarytablemodel.cpp b/src/library/analysislibrarytablemodel.cpp index 1c0bb7bcd4..2e726fb6aa 100644 --- a/src/library/analysislibrarytablemodel.cpp +++ b/src/library/analysislibrarytablemodel.cpp @@ -1,23 +1,19 @@ -#include <QObject> +#include "library/analysislibrarytablemodel.h" -#include "analysislibrarytablemodel.h" -#include "library/trackcollection.h" +namespace { const QString RECENT_FILTER = "datetime_added > datetime('now', '-7 days')"; +} // anonymous namespace + AnalysisLibraryTableModel::AnalysisLibraryTableModel(QObject* parent, - TrackCollection* pTrackCollection) - : LibraryTableModel(parent, pTrackCollection, + TrackCollectionManager* pTrackCollectionManager) + : LibraryTableModel(parent, pTrackCollectionManager, "mixxx.db.model.prepare") { // Default to showing recent tracks. setSearch("", RECENT_FILTER); } - -AnalysisLibraryTableModel::~AnalysisLibraryTableModel() { -} - - void AnalysisLibraryTableModel::showRecentSongs() { // Search with the recent filter. search(currentSearch(), RECENT_FILTER); diff --git a/src/library/analysislibrarytablemodel.h b/src/library/analysislibrarytablemodel.h index a3bfe38a6e..584bf0bab5 100644 --- a/src/library/analysislibrarytablemodel.h +++ b/ |