diff --git a/build/depends.py b/build/depends.py index 827caf56ad86..517da02111be 100644 --- a/build/depends.py +++ b/build/depends.py @@ -460,7 +460,7 @@ def sources(self, build): "dlgprefcrossfader.cpp", "dlgtagfetcher.cpp", "dlgtrackinfo.cpp", - "dlgprepare.cpp", + "dlganalysis.cpp", "dlgautodj.cpp", "dlghidden.cpp", "dlgmissing.cpp", @@ -574,23 +574,21 @@ def sources(self, build): "widget/wlibrarysidebar.cpp", "widget/wlibrary.cpp", "widget/wlibrarytableview.cpp", - "widget/wpreparelibrarytableview.cpp", - "widget/wpreparecratestableview.cpp", + "widget/wanalysislibrarytableview.cpp", "widget/wlibrarytextbrowser.cpp", - "library/preparecratedelegate.cpp", "library/trackcollection.cpp", "library/basesqltablemodel.cpp", "library/basetrackcache.cpp", "library/librarytablemodel.cpp", "library/searchqueryparser.cpp", - "library/preparelibrarytablemodel.cpp", + "library/analysislibrarytablemodel.cpp", "library/missingtablemodel.cpp", "library/hiddentablemodel.cpp", "library/proxytrackmodel.cpp", "library/playlisttablemodel.cpp", "library/libraryfeature.cpp", - "library/preparefeature.cpp", + "library/analysisfeature.cpp", "library/autodjfeature.cpp", "library/mixxxlibraryfeature.cpp", "library/baseplaylistfeature.cpp", @@ -780,7 +778,7 @@ def sources(self, build): build.env.Uic4('dlgaboutdlg.ui') build.env.Uic4('dlgtagfetcher.ui') build.env.Uic4('dlgtrackinfo.ui') - build.env.Uic4('dlgprepare.ui') + build.env.Uic4('dlganalysis.ui') build.env.Uic4('dlgautodj.ui') build.env.Uic4('dlgprefsounditem.ui') build.env.Uic4('dlgrecording.ui') diff --git a/src/analyserqueue.cpp b/src/analyserqueue.cpp index 8486a7b8d9f8..f5dfd021650d 100644 --- a/src/analyserqueue.cpp +++ b/src/analyserqueue.cpp @@ -403,7 +403,7 @@ AnalyserQueue* AnalyserQueue::createDefaultAnalyserQueue( } // static -AnalyserQueue* AnalyserQueue::createPrepareViewAnalyserQueue( +AnalyserQueue* AnalyserQueue::createAnalysisFeatureAnalyserQueue( ConfigObject* _config, TrackCollection* pTrackCollection) { AnalyserQueue* ret = new AnalyserQueue(pTrackCollection); diff --git a/src/analyserqueue.h b/src/analyserqueue.h index 207353732f76..7c0fe281a53d 100644 --- a/src/analyserqueue.h +++ b/src/analyserqueue.h @@ -25,7 +25,7 @@ class AnalyserQueue : public QThread { static AnalyserQueue* createDefaultAnalyserQueue( ConfigObject* _config, TrackCollection* pTrackCollection); - static AnalyserQueue* createPrepareViewAnalyserQueue( + static AnalyserQueue* createAnalysisFeatureAnalyserQueue( ConfigObject* _config, TrackCollection* pTrackCollection); public slots: diff --git a/src/dlganalysis.cpp b/src/dlganalysis.cpp new file mode 100644 index 000000000000..94bf5ec2dbe8 --- /dev/null +++ b/src/dlganalysis.cpp @@ -0,0 +1,166 @@ +#include + +#include "widget/wwidget.h" +#include "widget/wskincolor.h" +#include "transposeproxymodel.h" +#include "widget/wanalysislibrarytableview.h" +#include "library/trackcollection.h" +#include "dlganalysis.h" + + +DlgAnalysis::DlgAnalysis(QWidget* parent, + ConfigObject* pConfig, + TrackCollection* pTrackCollection) + : QWidget(parent), + m_pConfig(pConfig), + m_pTrackCollection(pTrackCollection), + m_bAnalysisActive(false), + m_tracksInQueue(0), + m_currentTrack(0) { + setupUi(this); + m_songsButtonGroup.addButton(radioButtonRecentlyAdded); + m_songsButtonGroup.addButton(radioButtonAllSongs); + + m_pAnalysisLibraryTableView = new WAnalysisLibraryTableView(this, pConfig, pTrackCollection); + connect(m_pAnalysisLibraryTableView, SIGNAL(loadTrack(TrackPointer)), + this, SIGNAL(loadTrack(TrackPointer))); + connect(m_pAnalysisLibraryTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString)), + this, SIGNAL(loadTrackToPlayer(TrackPointer, QString))); + + QBoxLayout* box = dynamic_cast(layout()); + Q_ASSERT(box); //Assumes the form layout is a QVBox/QHBoxLayout! + box->removeWidget(m_pTrackTablePlaceholder); + m_pTrackTablePlaceholder->hide(); + box->insertWidget(1, m_pAnalysisLibraryTableView); + + m_pAnalysisLibraryTableModel = new AnalysisLibraryTableModel(this, + pTrackCollection); + m_pAnalysisLibraryTableView->loadTrackModel(m_pAnalysisLibraryTableModel); + + connect(radioButtonRecentlyAdded, SIGNAL(clicked()), + this, SLOT(showRecentSongs())); + connect(radioButtonAllSongs, SIGNAL(clicked()), + this, SLOT(showAllSongs())); + + radioButtonRecentlyAdded->click(); + + labelProgress->setText(""); + pushButtonAnalyze->setEnabled(false); + connect(pushButtonAnalyze, SIGNAL(clicked()), + this, SLOT(analyze())); + + connect(pushButtonSelectAll, SIGNAL(clicked()), + this, SLOT(selectAll())); + + connect(m_pAnalysisLibraryTableView->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection&)), + this, + SLOT(tableSelectionChanged(const QItemSelection &, const QItemSelection&))); +} + +DlgAnalysis::~DlgAnalysis() { +} + +void DlgAnalysis::onShow() { + // Refresh table + // There might be new tracks dropped to other views + m_pAnalysisLibraryTableModel->select(); +} + +void DlgAnalysis::onSearch(const QString& text) { + m_pAnalysisLibraryTableModel->search(text); +} + +void DlgAnalysis::loadSelectedTrack() { + m_pAnalysisLibraryTableView->loadSelectedTrack(); +} + +void DlgAnalysis::loadSelectedTrackToGroup(QString group, bool play) { + m_pAnalysisLibraryTableView->loadSelectedTrackToGroup(group, play); +} + +void DlgAnalysis::moveSelection(int delta) { + m_pAnalysisLibraryTableView->moveSelection(delta); +} + +void DlgAnalysis::tableSelectionChanged(const QItemSelection& selected, + const QItemSelection& deselected) { + Q_UNUSED(selected); + Q_UNUSED(deselected); + bool tracksSelected = m_pAnalysisLibraryTableView->selectionModel()->hasSelection(); + pushButtonAnalyze->setEnabled(tracksSelected || m_bAnalysisActive); +} + +void DlgAnalysis::selectAll() { + m_pAnalysisLibraryTableView->selectAll(); +} + +void DlgAnalysis::analyze() { + //qDebug() << this << "analyze()"; + if (m_bAnalysisActive) { + emit(stopAnalysis()); + } else { + QList trackIds; + + QModelIndexList selectedIndexes = m_pAnalysisLibraryTableView->selectionModel()->selectedRows(); + foreach(QModelIndex selectedIndex, selectedIndexes) { + bool ok; + int trackId = selectedIndex.sibling( + selectedIndex.row(), + m_pAnalysisLibraryTableModel->fieldIndex(LIBRARYTABLE_ID)).data().toInt(&ok); + if (ok) { + trackIds.append(trackId); + } + } + m_currentTrack = 1; + emit(analyzeTracks(trackIds)); + } +} + +void DlgAnalysis::analysisActive(bool bActive) { + qDebug() << this << "analysisActive" << bActive; + m_bAnalysisActive = bActive; + if (bActive) { + pushButtonAnalyze->setEnabled(true); + pushButtonAnalyze->setText(tr("Stop Analysis")); + } else { + pushButtonAnalyze->setText(tr("Analyze")); + labelProgress->setText(""); + } +} + +// slot +void DlgAnalysis::trackAnalysisFinished(int size) { + qDebug() << "Analysis finished" << size << "tracks left"; + if (size > 0) { + m_currentTrack = m_tracksInQueue - size + 1; + } +} + +// slot +void DlgAnalysis::trackAnalysisProgress(int progress) { + if (m_bAnalysisActive) { + QString text = tr("Analyzing %1/%2 %3%").arg( + QString::number(m_currentTrack), + QString::number(m_tracksInQueue), + QString::number(progress)); + labelProgress->setText(text); + } +} + +void DlgAnalysis::trackAnalysisStarted(int size) { + m_tracksInQueue = size; +} + +void DlgAnalysis::showRecentSongs() { + m_pAnalysisLibraryTableModel->showRecentSongs(); +} + +void DlgAnalysis::showAllSongs() { + m_pAnalysisLibraryTableModel->showAllSongs(); +} + +void DlgAnalysis::installEventFilter(QObject* pFilter) { + QWidget::installEventFilter(pFilter); + m_pAnalysisLibraryTableView->installEventFilter(pFilter); +} diff --git a/src/dlgprepare.h b/src/dlganalysis.h similarity index 68% rename from src/dlgprepare.h rename to src/dlganalysis.h index 1e9aec492e50..631da6771d57 100644 --- a/src/dlgprepare.h +++ b/src/dlganalysis.h @@ -1,31 +1,30 @@ -#ifndef DLGTRIAGE_H -#define DLGTRIAGE_H +#ifndef DLGANALYSIS_H +#define DLGANALYSIS_H #include -#include "ui_dlgprepare.h" +#include "ui_dlganalysis.h" #include "configobject.h" #include "library/libraryview.h" #include "library/trackcollection.h" -#include "library/preparelibrarytablemodel.h" +#include "library/analysislibrarytablemodel.h" -class PrepareLibraryTableModel; -class WPrepareCratesTableView; -class WPrepareLibraryTableView; +class AnalysisLibraryTableModel; +class WAnalysisLibraryTableView; -class DlgPrepare : public QWidget, public Ui::DlgPrepare, public virtual LibraryView { +class DlgAnalysis : public QWidget, public Ui::DlgAnalysis, public virtual LibraryView { Q_OBJECT public: - DlgPrepare(QWidget *parent, + DlgAnalysis(QWidget *parent, ConfigObject* pConfig, TrackCollection* pTrackCollection); - virtual ~DlgPrepare(); + virtual ~DlgAnalysis(); virtual void onSearch(const QString& text); virtual void onShow(); virtual void loadSelectedTrack(); virtual void loadSelectedTrackToGroup(QString group, bool play); virtual void moveSelection(int delta); - inline const QString currentSearch() { return m_pPrepareLibraryTableModel->currentSearch(); }; + inline const QString currentSearch() { return m_pAnalysisLibraryTableModel->currentSearch(); }; public slots: void tableSelectionChanged(const QItemSelection& selected, @@ -34,6 +33,7 @@ class DlgPrepare : public QWidget, public Ui::DlgPrepare, public virtual Library void analyze(); void trackAnalysisFinished(int size); void trackAnalysisProgress(int progress); + void trackAnalysisStarted(int size); void showRecentSongs(); void showAllSongs(); void installEventFilter(QObject* pFilter); @@ -51,9 +51,8 @@ class DlgPrepare : public QWidget, public Ui::DlgPrepare, public virtual Library TrackCollection* m_pTrackCollection; bool m_bAnalysisActive; QButtonGroup m_songsButtonGroup; - WPrepareLibraryTableView* m_pPrepareLibraryTableView; - PrepareLibraryTableModel* m_pPrepareLibraryTableModel; - WPrepareCratesTableView* m_pPrepareCratesTableView; + WAnalysisLibraryTableView* m_pAnalysisLibraryTableView; + AnalysisLibraryTableModel* m_pAnalysisLibraryTableModel; int m_tracksInQueue; int m_currentTrack; }; diff --git a/src/dlgprepare.ui b/src/dlganalysis.ui similarity index 97% rename from src/dlgprepare.ui rename to src/dlganalysis.ui index 90dc26fa851c..1b293082cdb9 100644 --- a/src/dlgprepare.ui +++ b/src/dlganalysis.ui @@ -1,7 +1,7 @@ - DlgPrepare - + DlgAnalysis + 0 diff --git a/src/dlgprepare.cpp b/src/dlgprepare.cpp deleted file mode 100644 index a7c6b4fcfae6..000000000000 --- a/src/dlgprepare.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include -#include "widget/wwidget.h" -#include "widget/wskincolor.h" -#include "library/preparelibrarytablemodel.h" -#include "transposeproxymodel.h" -#include "widget/wpreparecratestableview.h" -#include "widget/wpreparelibrarytableview.h" -#include "library/trackcollection.h" -#include "dlgprepare.h" - - -DlgPrepare::DlgPrepare(QWidget* parent, - ConfigObject* pConfig, - TrackCollection* pTrackCollection) - : QWidget(parent), - m_pConfig(pConfig), - m_pTrackCollection(pTrackCollection), - m_bAnalysisActive(false), - m_tracksInQueue(0), - m_currentTrack(0) { - setupUi(this); - m_songsButtonGroup.addButton(radioButtonRecentlyAdded); - m_songsButtonGroup.addButton(radioButtonAllSongs); - - m_pPrepareLibraryTableView = new WPrepareLibraryTableView(this, pConfig, pTrackCollection); - connect(m_pPrepareLibraryTableView, SIGNAL(loadTrack(TrackPointer)), - this, SIGNAL(loadTrack(TrackPointer))); - connect(m_pPrepareLibraryTableView, SIGNAL(loadTrackToPlayer(TrackPointer, QString)), - this, SIGNAL(loadTrackToPlayer(TrackPointer, QString))); - - QBoxLayout* box = dynamic_cast(layout()); - Q_ASSERT(box); //Assumes the form layout is a QVBox/QHBoxLayout! - box->removeWidget(m_pTrackTablePlaceholder); - m_pTrackTablePlaceholder->hide(); - box->insertWidget(1, m_pPrepareLibraryTableView); - - m_pPrepareLibraryTableModel = new PrepareLibraryTableModel(this, - pTrackCollection); - m_pPrepareLibraryTableView->loadTrackModel(m_pPrepareLibraryTableModel); - -/* - m_pCrateView = new CrateView(this, pTrackCollection); - - m_pPrepareCratesTableView = new WPrepareCratesTableView(this, pTrackCollection); - box = dynamic_cast(horizontalLayoutCrates); - Q_ASSERT(box); //Assumes the form layout is a QVBox/QHBoxLayout! - box->removeWidget(m_pCratesViewPlaceholder); - m_pCratesViewPlaceholder->hide(); - //box->insertWidget(1, m_pPrepareCratesTableView); - box->insertWidget(1, m_pCrateView); - m_pCrateView->show(); - - m_pCratesTableModel = new QSqlTableModel(this); - m_pCratesTableModel->setTable("crates"); - m_pCratesTableModel->removeColumn(m_pCratesTableModel->fieldIndex("id")); - m_pCratesTableModel->removeColumn(m_pCratesTableModel->fieldIndex("show")); - m_pCratesTableModel->removeColumn(m_pCratesTableModel->fieldIndex("count")); - m_pCratesTableModel->setSort(m_pCratesTableModel->fieldIndex("name"), - Qt::AscendingOrder); - m_pCratesTableModel->setFilter("show = 1"); - m_pCratesTableModel->select(); - while (m_pCratesTableModel->canFetchMore()) { - m_pCratesTableModel->fetchMore(); - } - TransposeProxyModel* transposeProxy = new TransposeProxyModel(this); - transposeProxy->setSourceModel(m_pCratesTableModel); - m_pPrepareCratesTableView->setModel(m_pCratesTableModel); -*/ - - connect(radioButtonRecentlyAdded, SIGNAL(clicked()), - this, SLOT(showRecentSongs())); - connect(radioButtonAllSongs, SIGNAL(clicked()), - this, SLOT(showAllSongs())); - - radioButtonRecentlyAdded->click(); - - labelProgress->setText(""); - pushButtonAnalyze->setEnabled(false); - connect(pushButtonAnalyze, SIGNAL(clicked()), - this, SLOT(analyze())); - - connect(pushButtonSelectAll, SIGNAL(clicked()), - this, SLOT(selectAll())); - - connect(m_pPrepareLibraryTableView->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection&)), - this, - SLOT(tableSelectionChanged(const QItemSelection &, const QItemSelection&))); -} - -DlgPrepare::~DlgPrepare() { -} - -void DlgPrepare::onShow() { - // Refresh table - // There might be new tracks dropped to other views - m_pPrepareLibraryTableModel->select(); -} - -void DlgPrepare::onSearch(const QString& text) { - m_pPrepareLibraryTableModel->search(text); -} - -void DlgPrepare::loadSelectedTrack() { - m_pPrepareLibraryTableView->loadSelectedTrack(); -} - -void DlgPrepare::loadSelectedTrackToGroup(QString group, bool play) { - m_pPrepareLibraryTableView->loadSelectedTrackToGroup(group, play); -} - -void DlgPrepare::moveSelection(int delta) { - m_pPrepareLibraryTableView->moveSelection(delta); -} - -void DlgPrepare::tableSelectionChanged(const QItemSelection& selected, - const QItemSelection& deselected) { - Q_UNUSED(selected); - Q_UNUSED(deselected); - bool tracksSelected = m_pPrepareLibraryTableView->selectionModel()->hasSelection(); - pushButtonAnalyze->setEnabled(tracksSelected || m_bAnalysisActive); -} - -void DlgPrepare::selectAll() { - m_pPrepareLibraryTableView->selectAll(); -} - -void DlgPrepare::analyze() { - //qDebug() << this << "analyze()"; - if (m_bAnalysisActive) { - emit(stopAnalysis()); - } else { - QList trackIds; - - QModelIndexList selectedIndexes = m_pPrepareLibraryTableView->selectionModel()->selectedRows(); - foreach(QModelIndex selectedIndex, selectedIndexes) { - bool ok; - int trackId = selectedIndex.sibling( - selectedIndex.row(), - m_pPrepareLibraryTableModel->fieldIndex(LIBRARYTABLE_ID)).data().toInt(&ok); - if (ok) { - trackIds.append(trackId); - } - } - m_tracksInQueue = trackIds.count(); - m_currentTrack = 1; - emit(analyzeTracks(trackIds)); - } -} - -void DlgPrepare::analysisActive(bool bActive) { - qDebug() << this << "analysisActive" << bActive; - m_bAnalysisActive = bActive; - if (bActive) { - pushButtonAnalyze->setEnabled(true); - pushButtonAnalyze->setText(tr("Stop Analysis")); - } else { - pushButtonAnalyze->setText(tr("Analyze")); - labelProgress->setText(""); - } -} - -// slot -void DlgPrepare::trackAnalysisFinished(int size) { - qDebug() << "Analysis finished" << size << "tracks left"; - if (size > 0) { - m_currentTrack = m_tracksInQueue - size + 1; - } -} - -// slot -void DlgPrepare::trackAnalysisProgress(int progress) { - if (m_bAnalysisActive) { - QString text = tr("Analyzing %1/%2 %3%").arg( - QString::number(m_currentTrack), - QString::number(m_tracksInQueue), - QString::number(progress)); - labelProgress->setText(text); - } -} - -void DlgPrepare::showRecentSongs() { - m_pPrepareLibraryTableModel->showRecentSongs(); -} - -void DlgPrepare::showAllSongs() { - m_pPrepareLibraryTableModel->showAllSongs(); -} - -void DlgPrepare::installEventFilter(QObject* pFilter) { - QWidget::installEventFilter(pFilter); - m_pPrepareLibraryTableView->installEventFilter(pFilter); -} diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp new file mode 100644 index 000000000000..790118f658ec --- /dev/null +++ b/src/library/analysisfeature.cpp @@ -0,0 +1,154 @@ +// preparefeature.cpp +// Created 8/23/2009 by RJ Ryan (rryan@mit.edu) +// Forked 11/11/2009 by Albert Santoni (alberts@mixxx.org) + +#include + +#include "library/analysisfeature.h" +#include "library/librarytablemodel.h" +#include "library/trackcollection.h" +#include "dlganalysis.h" +#include "widget/wlibrary.h" +#include "mixxxkeyboard.h" +#include "analyserqueue.h" +#include "soundsourceproxy.h" + +const QString AnalysisFeature::m_sAnalysisViewName = QString("Analysis"); + +AnalysisFeature::AnalysisFeature(QObject* parent, + ConfigObject* pConfig, + TrackCollection* pTrackCollection) : + LibraryFeature(parent), + m_pConfig(pConfig), + m_pTrackCollection(pTrackCollection), + m_pAnalyserQueue(NULL) { +} + +AnalysisFeature::~AnalysisFeature() { + // TODO(XXX) delete these + //delete m_pLibraryTableModel; + cleanupAnalyser(); +} + +QVariant AnalysisFeature::title() { + return tr("Analyze"); +} + +QIcon AnalysisFeature::getIcon() { + return QIcon(":/images/library/ic_library_prepare.png"); +} + +void AnalysisFeature::bindWidget(WLibrary* libraryWidget, + MixxxKeyboard* keyboard) { + m_pAnalysisView = new DlgAnalysis(libraryWidget, + m_pConfig, + m_pTrackCollection); + connect(m_pAnalysisView, SIGNAL(loadTrack(TrackPointer)), + this, SIGNAL(loadTrack(TrackPointer))); + connect(m_pAnalysisView, SIGNAL(loadTrackToPlayer(TrackPointer, QString)), + this, SIGNAL(loadTrackToPlayer(TrackPointer, QString))); + connect(m_pAnalysisView, SIGNAL(analyzeTracks(QList)), + this, SLOT(analyzeTracks(QList))); + connect(m_pAnalysisView, SIGNAL(stopAnalysis()), + this, SLOT(stopAnalysis())); + + connect(this, SIGNAL(analysisActive(bool)), + m_pAnalysisView, SLOT(analysisActive(bool))); + connect(this, SIGNAL(trackAnalysisStarted(int)), + m_pAnalysisView, SLOT(trackAnalysisStarted(int))); + + m_pAnalysisView->installEventFilter(keyboard); + + // Let the DlgAnalysis know whether or not analysis is active. + bool bAnalysisActive = m_pAnalyserQueue != NULL; + emit(analysisActive(bAnalysisActive)); + + libraryWidget->registerView(m_sAnalysisViewName, m_pAnalysisView); +} + +TreeItemModel* AnalysisFeature::getChildModel() { + return &m_childModel; +} + +void AnalysisFeature::refreshLibraryModels() { + if (m_pAnalysisView) { + m_pAnalysisView->onShow(); + } +} + +void AnalysisFeature::activate() { + //qDebug() << "AnalysisFeature::activate()"; + emit(switchToView(m_sAnalysisViewName)); + if (m_pAnalysisView) { + emit(restoreSearch(m_pAnalysisView->currentSearch())); + } +} + +void AnalysisFeature::analyzeTracks(QList trackIds) { + if (m_pAnalyserQueue == NULL) { + // Save the old BPM detection prefs setting (on or off) + m_iOldBpmEnabled = m_pConfig->getValueString(ConfigKey("[BPM]","BPMDetectionEnabled")).toInt(); + // Force BPM detection to be on. + m_pConfig->set(ConfigKey("[BPM]","BPMDetectionEnabled"), ConfigValue(1)); + // Note: this sucks... we should refactor the prefs/analyser to fix this hacky bit ^^^^. + + m_pAnalyserQueue = AnalyserQueue::createAnalysisFeatureAnalyserQueue(m_pConfig, m_pTrackCollection); + + connect(m_pAnalyserQueue, SIGNAL(trackProgress(int)), + m_pAnalysisView, SLOT(trackAnalysisProgress(int))); + connect(m_pAnalyserQueue, SIGNAL(trackFinished(int)), + m_pAnalysisView, SLOT(trackAnalysisFinished(int))); + + connect(m_pAnalyserQueue, SIGNAL(queueEmpty()), + this, SLOT(cleanupAnalyser())); + emit(analysisActive(true)); + } + + foreach(int trackId, trackIds) { + TrackPointer pTrack = m_pTrackCollection->getTrackDAO().getTrack(trackId); + if (pTrack) { + //qDebug() << this << "Queueing track for analysis" << pTrack->getLocation(); + m_pAnalyserQueue->queueAnalyseTrack(pTrack); + } + } + emit(trackAnalysisStarted(trackIds.size())); +} + +void AnalysisFeature::stopAnalysis() { + //qDebug() << this << "stopAnalysis()"; + if (m_pAnalyserQueue != NULL) { + m_pAnalyserQueue->stop(); + } +} + +void AnalysisFeature::cleanupAnalyser() { + emit(analysisActive(false)); + if (m_pAnalyserQueue != NULL) { + m_pAnalyserQueue->stop(); + m_pAnalyserQueue->deleteLater(); + m_pAnalyserQueue = NULL; + // Restore old BPM detection setting for preferences... + m_pConfig->set(ConfigKey("[BPM]","BPMDetectionEnabled"), ConfigValue(m_iOldBpmEnabled)); + } +} + +bool AnalysisFeature::dropAccept(QList urls, QWidget *pSource) { + QList files; + foreach (QUrl url, urls) { + // XXX: Possible WTF alert - Previously we thought we needed toString() here + // but what you actually want in any case when converting a QUrl to a file + // system path is QUrl::toLocalFile(). This is the second time we have + // flip-flopped on this, but I think toLocalFile() should work in any + // case. toString() absolutely does not work when you pass the result to a + files.append(url.toLocalFile()); + } + // Adds track, does not insert duplicates, handles unremoving logic. + QList trackIds = m_pTrackCollection->getTrackDAO().addTracks(files, true); + analyzeTracks(trackIds); + return trackIds.size() > 0; +} + +bool AnalysisFeature::dragMoveAccept(QUrl url) { + QFileInfo file(url.toLocalFile()); + return SoundSourceProxy::isFilenameSupported(file.fileName()); +} diff --git a/src/library/preparefeature.h b/src/library/analysisfeature.h similarity index 74% rename from src/library/preparefeature.h rename to src/library/analysisfeature.h index 7fb6b1cb3a83..8acc8cc6efdc 100644 --- a/src/library/preparefeature.h +++ b/src/library/analysisfeature.h @@ -1,4 +1,4 @@ -// preparefeature.h +// analysisfeature.h // Created 8/23/2009 by RJ Ryan (rryan@mit.edu) // Forked 11/11/2009 by Albert Santoni (alberts@mixxx.org) @@ -9,23 +9,25 @@ #include "library/libraryfeature.h" #include "configobject.h" #include "treeitemmodel.h" -#include "dlgprepare.h" +#include "dlganalysis.h" class AnalyserQueue; class LibraryTableModel; class TrackCollection; -class PrepareFeature : public LibraryFeature { +class AnalysisFeature : public LibraryFeature { Q_OBJECT public: - PrepareFeature(QObject* parent, + AnalysisFeature(QObject* parent, ConfigObject* pConfig, TrackCollection* pTrackCollection); - virtual ~PrepareFeature(); + virtual ~AnalysisFeature(); QVariant title(); QIcon getIcon(); + bool dropAccept(QList urls, QWidget *pSource); + bool dragMoveAccept(QUrl url); void bindWidget(WLibrary* libraryWidget, MixxxKeyboard* keyboard); @@ -34,12 +36,13 @@ class PrepareFeature : public LibraryFeature { signals: void analysisActive(bool bActive); + void trackAnalysisStarted(int size); public slots: void activate(); + void analyzeTracks(QList trackIds); private slots: - void analyzeTracks(QList trackIds); void stopAnalysis(); void cleanupAnalyser(); @@ -50,9 +53,9 @@ class PrepareFeature : public LibraryFeature { // Used to temporarily enable BPM detection in the prefs before we analyse int m_iOldBpmEnabled; TreeItemModel m_childModel; - const static QString m_sPrepareViewName; - DlgPrepare* m_pPrepareView; + const static QString m_sAnalysisViewName; + DlgAnalysis* m_pAnalysisView; }; -#endif /* PREPAREFEATURE_H */ +#endif /* ANALYSISFEATURE_H */ diff --git a/src/library/preparelibrarytablemodel.cpp b/src/library/analysislibrarytablemodel.cpp similarity index 66% rename from src/library/preparelibrarytablemodel.cpp rename to src/library/analysislibrarytablemodel.cpp index b567fa21c9fd..7f1847b18610 100644 --- a/src/library/preparelibrarytablemodel.cpp +++ b/src/library/analysislibrarytablemodel.cpp @@ -1,11 +1,11 @@ #include -#include "preparelibrarytablemodel.h" +#include "analysislibrarytablemodel.h" #include "library/trackcollection.h" const QString RECENT_FILTER = "datetime_added > datetime('now', '-7 days')"; -PrepareLibraryTableModel::PrepareLibraryTableModel(QObject* parent, +AnalysisLibraryTableModel::AnalysisLibraryTableModel(QObject* parent, TrackCollection* pTrackCollection) : LibraryTableModel(parent, pTrackCollection, "mixxx.db.model.prepare") { @@ -15,16 +15,16 @@ PrepareLibraryTableModel::PrepareLibraryTableModel(QObject* parent, } -PrepareLibraryTableModel::~PrepareLibraryTableModel() { +AnalysisLibraryTableModel::~AnalysisLibraryTableModel() { } -void PrepareLibraryTableModel::showRecentSongs() { +void AnalysisLibraryTableModel::showRecentSongs() { m_bShowRecentSongs = true; search(currentSearch()); } -void PrepareLibraryTableModel::showAllSongs() { +void AnalysisLibraryTableModel::showAllSongs() { m_bShowRecentSongs = false; search(currentSearch()); } diff --git a/src/library/preparelibrarytablemodel.h b/src/library/analysislibrarytablemodel.h similarity index 54% rename from src/library/preparelibrarytablemodel.h rename to src/library/analysislibrarytablemodel.h index 2077acc75831..0c6d6540b75e 100644 --- a/src/library/preparelibrarytablemodel.h +++ b/src/library/analysislibrarytablemodel.h @@ -1,16 +1,16 @@ -#ifndef PREPARELIBRARYTABLEMODEL_H_ -#define PREPARELIBRARYTABLEMODEL_H_ +#ifndef ANALYSISLIBRARYTABLEMODEL_H_ +#define ANALYSISLIBRARYTABLEMODEL_H_ #include #include "librarytablemodel.h" -class PrepareLibraryTableModel : public LibraryTableModel +class AnalysisLibraryTableModel : public LibraryTableModel { Q_OBJECT public: - PrepareLibraryTableModel(QObject* parent, + AnalysisLibraryTableModel(QObject* parent, TrackCollection* pTrackCollection); - virtual ~PrepareLibraryTableModel(); + virtual ~AnalysisLibraryTableModel(); public slots: void showRecentSongs(); diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp index 0f9f7689d203..0601e466db95 100644 --- a/src/library/baseplaylistfeature.cpp +++ b/src/library/baseplaylistfeature.cpp @@ -58,6 +58,10 @@ BasePlaylistFeature::BasePlaylistFeature(QObject* parent, connect(m_pExportPlaylistAction, SIGNAL(triggered()), this, SLOT(slotExportPlaylist())); + m_pAnalyzePlaylistAction = new QAction(tr("Analyze entire Playlist"), this); + connect(m_pAnalyzePlaylistAction, SIGNAL(triggered()), + this, SLOT(slotAnalyzePlaylist())); + connect(&m_playlistDao, SIGNAL(added(int)), this, SLOT(slotPlaylistTableChanged(int))); @@ -82,6 +86,7 @@ BasePlaylistFeature::~BasePlaylistFeature() { delete m_pAddToAutoDJTopAction; delete m_pRenamePlaylistAction; delete m_pLockPlaylistAction; + delete m_pAnalyzePlaylistAction; } void BasePlaylistFeature::activate() { @@ -115,7 +120,7 @@ void BasePlaylistFeature::slotRenamePlaylist() { QString newName; bool validNameGiven = false; - do { + while (!validNameGiven) { bool ok = false; newName = QInputDialog::getText(NULL, tr("Rename Playlist"), @@ -134,16 +139,14 @@ void BasePlaylistFeature::slotRenamePlaylist() { QMessageBox::warning(NULL, tr("Renaming Playlist Failed"), tr("A playlist by that name already exists.")); - } - else if (newName.isEmpty()) { + } else if (newName.isEmpty()) { QMessageBox::warning(NULL, tr("Renaming Playlist Failed"), tr("A playlist cannot have a blank name.")); - } - else { + } else { validNameGiven = true; } - } while (!validNameGiven); + } m_playlistDao.renamePlaylist(playlistId, newName); } @@ -156,7 +159,7 @@ void BasePlaylistFeature::slotDuplicatePlaylist() { QString name; bool validNameGiven = false; - do { + while (!validNameGiven) { bool ok = false; name = QInputDialog::getText(NULL, tr("Duplicate Playlist"), @@ -176,16 +179,14 @@ void BasePlaylistFeature::slotDuplicatePlaylist() { QMessageBox::warning(NULL, tr("Playlist Creation Failed"), tr("A playlist by that name already exists.")); - } - else if (name.isEmpty()) { + } else if (name.isEmpty()) { QMessageBox::warning(NULL, tr("Playlist Creation Failed"), tr("A playlist cannot have a blank name.")); - } - else { + } else { validNameGiven = true; } - } while (!validNameGiven); + } int newPlaylistId = m_playlistDao.createPlaylist(name); @@ -213,7 +214,7 @@ void BasePlaylistFeature::slotCreatePlaylist() { QString name; bool validNameGiven = false; - do { + while (!validNameGiven) { bool ok = false; name = QInputDialog::getText(NULL, tr("New Playlist"), @@ -238,15 +239,13 @@ void BasePlaylistFeature::slotCreatePlaylist() { } else { validNameGiven = true; } - - } while (!validNameGiven); + } int playlistId = m_playlistDao.createPlaylist(name); if (playlistId != -1) { emit(showTrackModel(m_pPlaylistTableModel)); - } - else { + } else { QMessageBox::warning(NULL, tr("Playlist Creation Failed"), tr("An unknown error occurred while creating playlist: ") @@ -399,7 +398,7 @@ void BasePlaylistFeature::addToAutoDJ(bool bTop) { if (m_lastRightClickedIndex.isValid()) { int playlistId = m_playlistDao.getPlaylistIdFromName( - m_lastRightClickedIndex.data().toString()); + m_lastRightClickedIndex.data().toString()); if (playlistId >= 0) { // Insert this playlist m_playlistDao.addToAutoDJQueue(playlistId, bTop); @@ -407,6 +406,16 @@ void BasePlaylistFeature::addToAutoDJ(bool bTop) { } } +void BasePlaylistFeature::slotAnalyzePlaylist() { + if (m_lastRightClickedIndex.isValid()) { + int playlistId = m_playlistDao.getPlaylistIdFromName( + m_lastRightClickedIndex.data().toString()); + if (playlistId >= 0) { + QList ids = m_playlistDao.getTrackIds(playlistId); + emit(analyzeTracks(ids)); + } + } +} TreeItemModel* BasePlaylistFeature::getChildModel() { return &m_childModel; diff --git a/src/library/baseplaylistfeature.h b/src/library/baseplaylistfeature.h index 92e079811f96..bd945615e7d0 100644 --- a/src/library/baseplaylistfeature.h +++ b/src/library/baseplaylistfeature.h @@ -30,6 +30,7 @@ class BasePlaylistFeature : public LibraryFeature { signals: void showPage(const QUrl& page); + void analyzeTracks(QList); public slots: virtual void activate(); @@ -48,6 +49,7 @@ class BasePlaylistFeature : public LibraryFeature { void slotTogglePlaylistLock(); void slotImportPlaylist(); void slotExportPlaylist(); + void slotAnalyzePlaylist(); protected: virtual QModelIndex constructChildModel(int selected_id); @@ -70,6 +72,7 @@ class BasePlaylistFeature : public LibraryFeature { QAction *m_pImportPlaylistAction; QAction *m_pExportPlaylistAction; QAction *m_pDuplicatePlaylistAction; + QAction *m_pAnalyzePlaylistAction; QList > m_playlistList; QModelIndex m_lastRightClickedIndex; TreeItemModel m_childModel; diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp index 44bc349943a9..a911bf3a25cb 100644 --- a/src/library/cratefeature.cpp +++ b/src/library/cratefeature.cpp @@ -54,6 +54,10 @@ CrateFeature::CrateFeature(QObject* parent, connect(m_pDuplicateCrateAction, SIGNAL(triggered()), this, SLOT(slotDuplicateCrate())); + m_pAnalyzeCrateAction = new QAction(tr("Analyze entire Crate"),this); + connect(m_pAnalyzeCrateAction, SIGNAL(triggered()), + this, SLOT(slotAnalyzeCrate())); + connect(&m_crateDao, SIGNAL(added(int)), this, SLOT(slotCrateTableChanged(int))); @@ -80,6 +84,7 @@ CrateFeature::~CrateFeature() { delete m_pDuplicateCrateAction; delete m_pLockCrateAction; delete m_pImportPlaylistAction; + delete m_pAnalyzeCrateAction; } QVariant CrateFeature::title() { @@ -190,6 +195,7 @@ void CrateFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) menu.addAction(m_pDeleteCrateAction); menu.addAction(m_pLockCrateAction); menu.addSeparator(); + menu.addAction(m_pAnalyzeCrateAction); menu.addAction(m_pImportPlaylistAction); menu.addAction(m_pExportPlaylistAction); menu.exec(globalPos); @@ -200,7 +206,7 @@ void CrateFeature::slotCreateCrate() { QString name; bool validNameGiven = false; - do { + while (!validNameGiven) { bool ok = false; name = QInputDialog::getText(NULL, tr("New Crate"), @@ -217,17 +223,14 @@ void CrateFeature::slotCreateCrate() { QMessageBox::warning(NULL, tr("Creating Crate Failed"), tr("A crate by that name already exists.")); - } - else if (name.isEmpty()) { + } else if (name.isEmpty()) { QMessageBox::warning(NULL, tr("Creating Crate Failed"), tr("A crate cannot have a blank name.")); - } - else { + } else { validNameGiven = true; } - - } while (!validNameGiven); + } int crateId = m_crateDao.createCrate(name); @@ -275,7 +278,7 @@ void CrateFeature::slotRenameCrate() { QString newName; bool validNameGiven = false; - do { + while (!validNameGiven) { bool ok = false; newName = QInputDialog::getText(NULL, tr("Rename Crate"), @@ -294,17 +297,14 @@ void CrateFeature::slotRenameCrate() { QMessageBox::warning(NULL, tr("Renaming Crate Failed"), tr("A crate by that name already exists.")); - } - else if (newName.isEmpty()) { + } else if (newName.isEmpty()) { QMessageBox::warning(NULL, tr("Renaming Crate Failed"), tr("A crate cannot have a blank name.")); - } - else { + } else { validNameGiven = true; } - } while (!validNameGiven); - + } if (!m_crateDao.renameCrate(crateId, newName)) { qDebug() << "Failed to rename crateId" << crateId; @@ -318,7 +318,7 @@ void CrateFeature::slotDuplicateCrate() { QString name; bool validNameGiven = false; - do { + while (!validNameGiven) { bool ok = false; name = QInputDialog::getText(NULL, tr("Duplicate Crate"), @@ -338,16 +338,14 @@ void CrateFeature::slotDuplicateCrate() { QMessageBox::warning(NULL, tr("Renaming Crate Failed"), tr("A crate by that name already exists.")); - } - else if (name.isEmpty()) { + } else if (name.isEmpty()) { QMessageBox::warning(NULL, tr("Renaming Crate Failed"), tr("A crate cannot have a blank name.")); - } - else { + } else { validNameGiven = true; } - } while (!validNameGiven); + } int newCrateId = m_crateDao.createCrate(name); m_crateDao.copyCrateTracks(oldCrateId, newCrateId); @@ -360,12 +358,10 @@ void CrateFeature::slotDuplicateCrate() { tr("Creating Crate Failed"), tr("An unknown error occurred while creating crate: ") + name); - } } -void CrateFeature::slotToggleCrateLock() -{ +void CrateFeature::slotToggleCrateLock() { QString crateName = m_lastRightClickedIndex.data().toString(); int crateId = m_crateDao.getCrateIdByName(crateName); bool locked = !m_crateDao.isCrateLocked(crateId); @@ -403,8 +399,7 @@ void CrateFeature::buildCrateList() { * we require the sidebar model not to reset. * This method queries the database and does dynamic insertion */ -QModelIndex CrateFeature::constructChildModel(int selected_id) -{ +QModelIndex CrateFeature::constructChildModel(int selected_id) { buildCrateList(); QList data_list; int selected_row = -1; @@ -446,8 +441,7 @@ void CrateFeature::clearChildModel() { m_crateList.clear(); } -void CrateFeature::slotImportPlaylist() -{ +void CrateFeature::slotImportPlaylist() { qDebug() << "slotImportPlaylist() row:" ; //<< m_lastRightClickedIndex.data(); @@ -484,7 +478,18 @@ void CrateFeature::slotImportPlaylist() delete playlist_parser; } -void CrateFeature::slotExportPlaylist(){ +void CrateFeature::slotAnalyzeCrate() { + if (m_lastRightClickedIndex.isValid()) { + int playlistId = m_crateDao.getCrateIdByName( + m_lastRightClickedIndex.data().toString()); + if (playlistId >= 0) { + QList ids = m_crateDao.getTrackIds(playlistId); + emit(analyzeTracks(ids)); + } + } +} + +void CrateFeature::slotExportPlaylist() { qDebug() << "Export crate" << m_lastRightClickedIndex.data(); QString file_location = QFileDialog::getSaveFileName( NULL, diff --git a/src/library/cratefeature.h b/src/library/cratefeature.h index e54a97d6f7ef..ab5158b99e3a 100644 --- a/src/library/cratefeature.h +++ b/src/library/cratefeature.h @@ -34,6 +34,9 @@ class CrateFeature : public LibraryFeature { TreeItemModel* getChildModel(); + signals: + void analyzeTracks(QList); + public slots: void activate(); void activateChild(const QModelIndex& index); @@ -47,6 +50,7 @@ class CrateFeature : public LibraryFeature { void slotToggleCrateLock(); void slotImportPlaylist(); void slotExportPlaylist(); + void slotAnalyzeCrate(); void slotCrateTableChanged(int playlistId); void htmlLinkClicked(const QUrl & link); @@ -65,6 +69,7 @@ class CrateFeature : public LibraryFeature { QAction *m_pDuplicateCrateAction; QAction *m_pImportPlaylistAction; QAction *m_pExportPlaylistAction; + QAction *m_pAnalyzeCrateAction; QList > m_crateList; CrateTableModel m_crateTableModel; QModelIndex m_lastRightClickedIndex; diff --git a/src/library/dao/cratedao.cpp b/src/library/dao/cratedao.cpp index 6edbec017992..519e1cb357a6 100644 --- a/src/library/dao/cratedao.cpp +++ b/src/library/dao/cratedao.cpp @@ -93,6 +93,23 @@ bool CrateDAO::isCrateLocked(int crateId) { return false; } +QList CrateDAO::getTrackIds(int crateId) { + QSqlQuery query(m_database); + query.prepare("SELECT track_id from crate_tracks WHERE crate_id = :id"); + query.bindValue(":id", crateId); + + if (!query.exec()) { + LOG_FAILED_QUERY(query); + return QList (); + } + + QList ids; + while (query.next()) { + ids.append(query.value(query.record().indexOf("track_id")).toInt()); + } + return ids; +} + bool CrateDAO::deleteCrate(int crateId) { ScopedTransaction transaction(m_database); QSqlQuery query(m_database); diff --git a/src/library/dao/cratedao.h b/src/library/dao/cratedao.h index 7e7f048d6263..bcd27e6bca33 100644 --- a/src/library/dao/cratedao.h +++ b/src/library/dao/cratedao.h @@ -38,6 +38,7 @@ class CrateDAO : public QObject, public virtual DAO { QString crateName(int crateId); unsigned int crateSize(int crateId); bool addTrackToCrate(int trackId, int crateId); + QList getTrackIds(int crateId); // This method takes a list of track ids to be added to crate and returns // the number of successful insertions. int addTracksToCrate(QList trackIdList, int crateId); diff --git a/src/library/dao/playlistdao.cpp b/src/library/dao/playlistdao.cpp index bc120bfbe774..581925d6def8 100644 --- a/src/library/dao/playlistdao.cpp +++ b/src/library/dao/playlistdao.cpp @@ -11,16 +11,13 @@ PlaylistDAO::PlaylistDAO(QSqlDatabase& database) : m_database(database) { } -PlaylistDAO::~PlaylistDAO() -{ +PlaylistDAO::~PlaylistDAO() { } -void PlaylistDAO::initialize() -{ +void PlaylistDAO::initialize() { } -int PlaylistDAO::createPlaylist(QString name, HiddenType hidden) -{ +int PlaylistDAO::createPlaylist(QString name, HiddenType hidden) { // qDebug() << "PlaylistDAO::createPlaylist" // << QThread::currentThread() // << m_database.connectionName(); @@ -64,8 +61,7 @@ int PlaylistDAO::createPlaylist(QString name, HiddenType hidden) return playlistId; } -QString PlaylistDAO::getPlaylistName(int playlistId) -{ +QString PlaylistDAO::getPlaylistName(int playlistId) { // qDebug() << "PlaylistDAO::getPlaylistName" << QThread::currentThread() << m_database.connectionName(); QSqlQuery query(m_database); @@ -86,6 +82,24 @@ QString PlaylistDAO::getPlaylistName(int playlistId) return name; } +QList PlaylistDAO::getTrackIds(int playlistId) { + QSqlQuery query(m_database); + query.prepare("SELECT DISTINCT track_id from PlaylistTracks " + "WHERE playlist_id = :id"); + query.bindValue(":id", playlistId); + + if (!query.exec()) { + LOG_FAILED_QUERY(query); + return QList (); + } + + QList ids; + while (query.next()) { + ids.append(query.value(query.record().indexOf("track_id")).toInt()); + } + return ids; +} + int PlaylistDAO::getPlaylistIdFromName(QString name) { // qDebug() << "PlaylistDAO::getPlaylistIdFromName" << QThread::currentThread() << m_database.connectionName(); diff --git a/src/library/dao/playlistdao.h b/src/library/dao/playlistdao.h index 0d2268a0e8f2..0ee1cf34b40d 100644 --- a/src/library/dao/playlistdao.h +++ b/src/library/dao/playlistdao.h @@ -57,6 +57,7 @@ class PlaylistDAO : public QObject, public virtual DAO { // position in the database table, not the display order position column // stored in the database. int getPlaylistId(int index); + QList getTrackIds(int playlistId); // Returns true if the playlist with playlistId is hidden bool isHidden(int playlistId); // Returns the HiddenType of playlistId diff --git a/src/library/library.cpp b/src/library/library.cpp index 99ae05def3ed..9d05cecd4979 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -17,7 +17,6 @@ #include "library/mixxxlibraryfeature.h" #include "library/autodjfeature.h" #include "library/playlistfeature.h" -#include "library/preparefeature.h" #ifdef __PROMO__ #include "library/promotracksfeature.h" #endif @@ -67,8 +66,12 @@ Library::Library(QObject* parent, ConfigObject* pConfig, bool first addFeature(new BrowseFeature(this, pConfig, m_pTrackCollection, m_pRecordingManager)); addFeature(new RecordingFeature(this, pConfig, m_pTrackCollection, m_pRecordingManager)); addFeature(new SetlogFeature(this, pConfig, m_pTrackCollection)); - m_pPrepareFeature = new PrepareFeature(this, pConfig, m_pTrackCollection); - addFeature(m_pPrepareFeature); + m_pAnalysisFeature = new AnalysisFeature(this, pConfig, m_pTrackCollection); + connect(m_pPlaylistFeature, SIGNAL(analyzeTracks(QList)), + m_pAnalysisFeature, SLOT(analyzeTracks(QList))); + connect(m_pCrateFeature, SIGNAL(analyzeTracks(QList)), + m_pAnalysisFeature, SLOT(analyzeTracks(QList))); + addFeature(m_pAnalysisFeature); //iTunes and Rhythmbox should be last until we no longer have an obnoxious //messagebox popup when you select them. (This forces you to reach for your //mouse or keyboard if you're using MIDI control and you scroll through them...) @@ -219,7 +222,7 @@ void Library::slotRestoreSearch(const QString& text) { void Library::slotRefreshLibraryModels() { m_pMixxxLibraryFeature->refreshLibraryModels(); - m_pPrepareFeature->refreshLibraryModels(); + m_pAnalysisFeature->refreshLibraryModels(); } void Library::slotCreatePlaylist() { diff --git a/src/library/library.h b/src/library/library.h index 5c6b4ba9e703..1390dacc398c 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -14,7 +14,7 @@ #include "configobject.h" #include "trackinfoobject.h" #include "recording/recordingmanager.h" -#include "preparefeature.h" +#include "analysisfeature.h" class TrackModel; class TrackCollection; @@ -91,7 +91,7 @@ class Library : public QObject { class PromoTracksFeature; PromoTracksFeature* m_pPromoTracksFeature; #endif - PrepareFeature* m_pPrepareFeature; + AnalysisFeature* m_pAnalysisFeature; LibraryControl* m_pLibraryControl; RecordingManager* m_pRecordingManager; }; diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index a3ad8faf494a..a11e575e097e 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -133,8 +133,7 @@ TreeItemModel* MixxxLibraryFeature::getChildModel() { return &m_childModel; } -void MixxxLibraryFeature::refreshLibraryModels() -{ +void MixxxLibraryFeature::refreshLibraryModels() { if (m_pLibraryTableModel) { m_pLibraryTableModel->select(); } diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp index fa6df2545aa0..d7dd2d55310f 100644 --- a/src/library/playlistfeature.cpp +++ b/src/library/playlistfeature.cpp @@ -78,6 +78,7 @@ void PlaylistFeature::onRightClickChild(const QPoint& globalPos, QModelIndex ind menu.addAction(m_pDeletePlaylistAction); menu.addAction(m_pLockPlaylistAction); menu.addSeparator(); + menu.addAction(m_pAnalyzePlaylistAction); menu.addAction(m_pImportPlaylistAction); menu.addAction(m_pExportPlaylistAction); menu.exec(globalPos); diff --git a/src/library/preparecratedelegate.cpp b/src/library/preparecratedelegate.cpp deleted file mode 100644 index dfe70bbf7c13..000000000000 --- a/src/library/preparecratedelegate.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include "preparecratedelegate.h" - -PrepareCrateDelegate::PrepareCrateDelegate(QObject* parent) : QItemDelegate(parent) { - - m_pCratePixmap = new QPixmap(":images/library/crate_empty.png"); -} - -PrepareCrateDelegate::~PrepareCrateDelegate() -{ - delete m_pCratePixmap; -} - -void PrepareCrateDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const -{ - painter->save(); - - if (qVariantCanConvert(index.data())) - { - QString crateName = qVariantValue(index.data()); - painter->drawPixmap(option.rect, *m_pCratePixmap); - painter->drawText(option.rect, crateName); - } - painter->restore(); -} diff --git a/src/library/preparecratedelegate.h b/src/library/preparecratedelegate.h deleted file mode 100644 index fb0d0c7127e9..000000000000 --- a/src/library/preparecratedelegate.h +++ /dev/null @@ -1,11 +0,0 @@ -#include -class QPixmap; - -class PrepareCrateDelegate : public QItemDelegate { - public: -PrepareCrateDelegate(QObject* parent); -~PrepareCrateDelegate(); -void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const; - private: - QPixmap* m_pCratePixmap; -}; diff --git a/src/library/preparefeature.cpp b/src/library/preparefeature.cpp deleted file mode 100644 index c1ecd1e1ea97..000000000000 --- a/src/library/preparefeature.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// preparefeature.cpp -// Created 8/23/2009 by RJ Ryan (rryan@mit.edu) -// Forked 11/11/2009 by Albert Santoni (alberts@mixxx.org) - -#include - -#include "library/preparefeature.h" -#include "library/librarytablemodel.h" -#include "library/trackcollection.h" -#include "dlgprepare.h" -#include "widget/wlibrary.h" -#include "mixxxkeyboard.h" -#include "analyserqueue.h" - -const QString PrepareFeature::m_sPrepareViewName = QString("Prepare"); - -PrepareFeature::PrepareFeature(QObject* parent, - ConfigObject* pConfig, - TrackCollection* pTrackCollection) : - LibraryFeature(parent), - m_pConfig(pConfig), - m_pTrackCollection(pTrackCollection), - m_pAnalyserQueue(NULL) { -} - -PrepareFeature::~PrepareFeature() { - // TODO(XXX) delete these - //delete m_pLibraryTableModel; - cleanupAnalyser(); -} - -QVariant PrepareFeature::title() { - return tr("Analyze"); -} - -QIcon PrepareFeature::getIcon() { - return QIcon(":/images/library/ic_library_prepare.png"); -} - -void PrepareFeature::bindWidget(WLibrary* libraryWidget, - MixxxKeyboard* keyboard) { - m_pPrepareView = new DlgPrepare(libraryWidget, - m_pConfig, - m_pTrackCollection); - connect(m_pPrepareView, SIGNAL(loadTrack(TrackPointer)), - this, SIGNAL(loadTrack(TrackPointer))); - connect(m_pPrepareView, SIGNAL(loadTrackToPlayer(TrackPointer, QString)), - this, SIGNAL(loadTrackToPlayer(TrackPointer, QString))); - connect(m_pPrepareView, SIGNAL(analyzeTracks(QList)), - this, SLOT(analyzeTracks(QList))); - connect(m_pPrepareView, SIGNAL(stopAnalysis()), - this, SLOT(stopAnalysis())); - - connect(this, SIGNAL(analysisActive(bool)), - m_pPrepareView, SLOT(analysisActive(bool))); - - m_pPrepareView->installEventFilter(keyboard); - - // Let the DlgPrepare know whether or not analysis is active. - bool bAnalysisActive = m_pAnalyserQueue != NULL; - emit(analysisActive(bAnalysisActive)); - - libraryWidget->registerView(m_sPrepareViewName, m_pPrepareView); -} - -TreeItemModel* PrepareFeature::getChildModel() { - return &m_childModel; -} - -void PrepareFeature::refreshLibraryModels() { - if (m_pPrepareView) { - m_pPrepareView->onShow(); - } -} - -void PrepareFeature::activate() { - //qDebug() << "PrepareFeature::activate()"; - emit(switchToView(m_sPrepareViewName)); - if (m_pPrepareView) { - emit(restoreSearch(m_pPrepareView->currentSearch())); - } -} - -void PrepareFeature::analyzeTracks(QList trackIds) { - if (m_pAnalyserQueue == NULL) { - // Save the old BPM detection prefs setting (on or off) - m_iOldBpmEnabled = m_pConfig->getValueString(ConfigKey("[BPM]","BPMDetectionEnabled")).toInt(); - // Force BPM detection to be on. - m_pConfig->set(ConfigKey("[BPM]","BPMDetectionEnabled"), ConfigValue(1)); - // Note: this sucks... we should refactor the prefs/analyser to fix this hacky bit ^^^^. - - m_pAnalyserQueue = AnalyserQueue::createPrepareViewAnalyserQueue(m_pConfig, m_pTrackCollection); - - connect(m_pAnalyserQueue, SIGNAL(trackProgress(int)), - m_pPrepareView, SLOT(trackAnalysisProgress(int))); - connect(m_pAnalyserQueue, SIGNAL(trackFinished(int)), - m_pPrepareView, SLOT(trackAnalysisFinished(int))); - - connect(m_pAnalyserQueue, SIGNAL(queueEmpty()), - this, SLOT(cleanupAnalyser())); - emit(analysisActive(true)); - } - - foreach(int trackId, trackIds) { - TrackPointer pTrack = m_pTrackCollection->getTrackDAO().getTrack(trackId); - if (pTrack) { - //qDebug() << this << "Queueing track for analysis" << pTrack->getLocation(); - m_pAnalyserQueue->queueAnalyseTrack(pTrack); - } - } -} - -void PrepareFeature::stopAnalysis() { - //qDebug() << this << "stopAnalysis()"; - if (m_pAnalyserQueue != NULL) { - m_pAnalyserQueue->stop(); - } -} - -void PrepareFeature::cleanupAnalyser() { - emit(analysisActive(false)); - if (m_pAnalyserQueue != NULL) { - m_pAnalyserQueue->stop(); - m_pAnalyserQueue->deleteLater(); - m_pAnalyserQueue = NULL; - // Restore old BPM detection setting for preferences... - m_pConfig->set(ConfigKey("[BPM]","BPMDetectionEnabled"), ConfigValue(m_iOldBpmEnabled)); - } -} diff --git a/src/widget/wpreparelibrarytableview.cpp b/src/widget/wanalysislibrarytableview.cpp similarity index 57% rename from src/widget/wpreparelibrarytableview.cpp rename to src/widget/wanalysislibrarytableview.cpp index 664b73be52fc..e670d46da3a6 100644 --- a/src/widget/wpreparelibrarytableview.cpp +++ b/src/widget/wanalysislibrarytableview.cpp @@ -1,8 +1,8 @@ #include "library/trackcollection.h" -#include "widget/wpreparelibrarytableview.h" +#include "widget/wanalysislibrarytableview.h" -WPrepareLibraryTableView::WPrepareLibraryTableView(QWidget* parent, +WAnalysisLibraryTableView::WAnalysisLibraryTableView(QWidget* parent, ConfigObject* pConfig, TrackCollection* pTrackCollection) : WTrackTableView(parent, pConfig, pTrackCollection) @@ -11,17 +11,17 @@ WPrepareLibraryTableView::WPrepareLibraryTableView(QWidget* parent, setDragEnabled(true); //Always enable drag for now (until we have a model that doesn't support this.) } -WPrepareLibraryTableView::~WPrepareLibraryTableView() +WAnalysisLibraryTableView::~WAnalysisLibraryTableView() { } -void WPrepareLibraryTableView::onSearchStarting() { +void WAnalysisLibraryTableView::onSearchStarting() { } -void WPrepareLibraryTableView::onSearchCleared() { +void WAnalysisLibraryTableView::onSearchCleared() { } -void WPrepareLibraryTableView::onSearch(const QString& text) { +void WAnalysisLibraryTableView::onSearch(const QString& text) { Q_UNUSED(text); } diff --git a/src/widget/wpreparelibrarytableview.h b/src/widget/wanalysislibrarytableview.h similarity index 56% rename from src/widget/wpreparelibrarytableview.h rename to src/widget/wanalysislibrarytableview.h index d4cddbc1d055..edd71bf97e61 100644 --- a/src/widget/wpreparelibrarytableview.h +++ b/src/widget/wanalysislibrarytableview.h @@ -1,5 +1,5 @@ -#ifndef WPREPARELIBRARYTABLEVIEW_H -#define WPREPARELIBRARYTABLEVIEW_H +#ifndef WANALYSISLIBRARYTABLEVIEW_H +#define WANALYSISLIBRARYTABLEVIEW_H #include @@ -8,12 +8,12 @@ class TrackCollection; -class WPrepareLibraryTableView : public WTrackTableView +class WAnalysisLibraryTableView : public WTrackTableView { public: - WPrepareLibraryTableView(QWidget* parent, ConfigObject* pConfig, + WAnalysisLibraryTableView(QWidget* parent, ConfigObject* pConfig, TrackCollection* pTrackCollection); - ~WPrepareLibraryTableView(); + ~WAnalysisLibraryTableView(); virtual void onSearchStarting(); virtual void onSearchCleared(); diff --git a/src/widget/wpreparecratestableview.cpp b/src/widget/wpreparecratestableview.cpp deleted file mode 100644 index 02f9b8760c9e..000000000000 --- a/src/widget/wpreparecratestableview.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -#include -#include "library/trackcollection.h" -#include "library/dao/trackdao.h" -#include "library/dao/cratedao.h" -#include "library/preparecratedelegate.h" -#include "wpreparecratestableview.h" - - -WPrepareCratesTableView::WPrepareCratesTableView(QWidget* parent, TrackCollection* pTrackCollection) : QTableView(parent) -{ - m_pTrackCollection = pTrackCollection; - setAcceptDrops(true); - setShowGrid(false); - setSelectionMode(QAbstractItemView::NoSelection); - - //Hack the max height into here so it doesn't go giant - setMaximumHeight(51); - - horizontalHeader()->hide(); - verticalHeader()->hide(); - - setItemDelegate(new PrepareCrateDelegate(this)); -} - -WPrepareCratesTableView::~WPrepareCratesTableView() -{ -} - - -/** Drag enter event, happens when a dragged item hovers over the track table view*/ -void WPrepareCratesTableView::dragEnterEvent(QDragEnterEvent * event) -{ - //qDebug() << "dragEnterEvent" << event->mimeData()->formats(); - if (event->mimeData()->hasUrls()) - { - if (event->source() == this) { - event->ignore(); - } else { - event->acceptProposedAction(); - } - } else { - event->ignore(); - } -} - -/** Drag move event, happens when a dragged item hovers over the track table view... - * Why we need this is a little vague, but without it, drag-and-drop just doesn't work. - * -- Albert June 8/08 - */ -void WPrepareCratesTableView::dragMoveEvent(QDragMoveEvent * event) -{ - //qDebug() << "dragMoveEvent" << event->mimeData()->formats(); - if (event->mimeData()->hasUrls()) - { - if (event->source() == this) { - event->ignore(); - } else { - event->acceptProposedAction(); - } - } else { - event->ignore(); - } -} - -/** Drag-and-drop "drop" event. Occurs when something is dropped onto the track table view */ -void WPrepareCratesTableView::dropEvent(QDropEvent * event) -{ - if (event->mimeData()->hasUrls()) { - QList urls(event->mimeData()->urls()); - QUrl url; - QModelIndex destIndex; - - //Drag and drop within this widget (crate reordering) - if (event->source() == this) - { - event->ignore(); - } - else - { - //Drag-and-drop from an external widget - - destIndex = this->indexAt(event->pos()); - foreach (url, urls) - { - QModelIndex destIndex = this->indexAt(event->pos()); - QString crateName = destIndex.data().toString(); - int crateId = m_pTrackCollection->getCrateDAO().getCrateIdByName(crateName); - int trackId = m_pTrackCollection->getTrackDAO().getTrackId(url.toLocalFile()); - if (trackId >= 0) - m_pTrackCollection->getCrateDAO().addTrackToCrate(trackId, crateId); - } - } - - event->acceptProposedAction(); - - } else { - event->ignore(); - } -} diff --git a/src/widget/wpreparecratestableview.h b/src/widget/wpreparecratestableview.h deleted file mode 100644 index 7e448635933c..000000000000 --- a/src/widget/wpreparecratestableview.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef WPREPARECRATESTABLEVIEW_H_ -#define WPREPARECRATESTABLEVIEW_H_ - -#include -class TrackCollection; -class QDropEvent; -class QDragMoveEvent; -class QDragEnterEvent; - -class WPrepareCratesTableView : public QTableView -{ - public: - WPrepareCratesTableView(QWidget* parent, TrackCollection* pTrackCollection); - ~WPrepareCratesTableView(); - - virtual void dropEvent(QDropEvent * event); - virtual void dragMoveEvent(QDragMoveEvent * event); - virtual void dragEnterEvent(QDragEnterEvent * event); - private: - TrackCollection* m_pTrackCollection; - -}; - -#endif