summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/dlgtrackinfo.cpp14
-rw-r--r--src/dlgtrackinfo.h1
-rw-r--r--src/library/coverartcache.cpp22
-rw-r--r--src/library/coverartcache.h11
-rw-r--r--src/widget/wcoverart.cpp11
-rw-r--r--src/widget/wcoverart.h1
-rw-r--r--src/widget/wcoverartlabel.cpp2
-rw-r--r--src/widget/wcoverartlabel.h1
-rw-r--r--src/widget/wcoverartmenu.cpp8
-rw-r--r--src/widget/wcoverartmenu.h2
-rw-r--r--src/widget/wtracktableview.cpp53
-rw-r--r--src/widget/wtracktableview.h3
12 files changed, 112 insertions, 17 deletions
diff --git a/src/dlgtrackinfo.cpp b/src/dlgtrackinfo.cpp
index abe9da6a92..24120ca4ba 100644
--- a/src/dlgtrackinfo.cpp
+++ b/src/dlgtrackinfo.cpp
@@ -7,6 +7,7 @@
#include "dlgtrackinfo.h"
#include "trackinfoobject.h"
#include "library/coverartcache.h"
+#include "library/coverartutils.h"
#include "library/dao/cue.h"
const int kMinBPM = 30;
@@ -80,6 +81,8 @@ void DlgTrackInfo::init(){
}
connect(m_pWCoverArtLabel, SIGNAL(coverArtSelected(const CoverArt&)),
this, SLOT(slotCoverArtSelected(const CoverArt&)));
+ connect(m_pWCoverArtLabel, SIGNAL(reloadCover()),
+ this, SLOT(slotReloadCoverArt()));
}
void DlgTrackInfo::OK() {
@@ -205,6 +208,17 @@ void DlgTrackInfo::slotCoverFound(const QObject* pRequestor,
}
}
+void DlgTrackInfo::slotReloadCoverArt() {
+ if (m_pLoadedTrack) {
+ // TODO(rryan) move this out of the main thread. The issue is that
+ // CoverArtCache::requestGuessCover mutates the provided track whereas
+ // in DlgTrackInfo we delay changing the track until the user hits apply
+ // (or cancels the edit).
+ CoverArt art = CoverArtUtils::guessCoverArt(m_pLoadedTrack);
+ slotCoverArtSelected(art);
+ }
+}
+
void DlgTrackInfo::slotCoverArtSelected(const CoverArt& art) {
qDebug() << "DlgTrackInfo::slotCoverArtSelected" << art;
m_loadedCoverInfo = art.info;
diff --git a/src/dlgtrackinfo.h b/src/dlgtrackinfo.h
index ef88a5c27c..8d469c0d3f 100644
--- a/src/dlgtrackinfo.h
+++ b/src/dlgtrackinfo.h
@@ -58,6 +58,7 @@ class DlgTrackInfo : public QDialog, public Ui::DlgTrackInfo {
void slotCoverFound(const QObject* pRequestor, int requestReference,
const CoverInfo& info, QPixmap pixmap, bool fromCache);
void slotCoverArtSelected(const CoverArt& art);
+ void slotReloadCoverArt();
private:
void populateFields(TrackPointer pTrack);
diff --git a/src/library/coverartcache.cpp b/src/library/coverartcache.cpp
index 212045e727..3d1e30de5d 100644
--- a/src/library/coverartcache.cpp
+++ b/src/library/coverartcache.cpp
@@ -152,3 +152,25 @@ void CoverArtCache::coverLoaded() {
res.cover.info, pixmap, false));
}
}
+
+void CoverArtCache::requestGuessCovers(QList<TrackPointer> tracks) {
+ QtConcurrent::run(this, &CoverArtCache::guessCovers, tracks);
+}
+
+void CoverArtCache::requestGuessCover(TrackPointer pTrack) {
+ QtConcurrent::run(this, &CoverArtCache::guessCover, pTrack);
+}
+
+void CoverArtCache::guessCover(TrackPointer pTrack) {
+ if (pTrack) {
+ pTrack->setCoverArt(CoverArtUtils::guessCoverArt(pTrack));
+ }
+}
+
+void CoverArtCache::guessCovers(QList<TrackPointer> tracks) {
+ qDebug() << "CoverArtCache::guessCovers guessing covers for"
+ << tracks.size() << "tracks";
+ foreach (TrackPointer pTrack, tracks) {
+ guessCover(pTrack);
+ }
+}
diff --git a/src/library/coverartcache.h b/src/library/coverartcache.h
index 990c5140d6..0db4171122 100644
--- a/src/library/coverartcache.h
+++ b/src/library/coverartcache.h
@@ -6,6 +6,7 @@
#include "library/coverart.h"
#include "util/singleton.h"
+#include "trackinfoobject.h"
class CoverArtCache : public QObject, public Singleton<CoverArtCache> {
Q_OBJECT
@@ -32,6 +33,12 @@ class CoverArtCache : public QObject, public Singleton<CoverArtCache> {
const bool onlyCached = false,
const bool signalWhenDone = true);
+ // Guesses the cover art for the provided tracks by searching the tracks'
+ // metadata and folders for image files. All I/O is done in a separate
+ // thread.
+ void requestGuessCovers(QList<TrackPointer> tracks);
+ void requestGuessCover(TrackPointer pTrack);
+
struct FutureResult {
FutureResult() : pRequestor(NULL),
requestReference(0),
@@ -67,6 +74,10 @@ class CoverArtCache : public QObject, public Singleton<CoverArtCache> {
const int desiredWidth,
const bool emitSignals);
+ // Guesses the cover art for each track.
+ void guessCovers(QList<TrackPointer> tracks);
+ void guessCover(TrackPointer pTrack);
+
private:
QSet<QPair<const QObject*, int> > m_runningRequests;
};
diff --git a/src/widget/wcoverart.cpp b/src/widget/wcoverart.cpp
index d7321f02f2..2c9b42a6fb 100644
--- a/src/widget/wcoverart.cpp
+++ b/src/widget/wcoverart.cpp
@@ -36,6 +36,8 @@ WCoverArt::WCoverArt(QWidget* parent,
}
connect(m_pMenu, SIGNAL(coverArtSelected(const CoverArt&)),
this, SLOT(slotCoverArtSelected(const CoverArt&)));
+ connect(m_pMenu, SIGNAL(reloadCoverArt()),
+ this, SLOT(slotReloadCoverArt()));
}
WCoverArt::~WCoverArt() {
@@ -78,6 +80,15 @@ void WCoverArt::setup(QDomNode node, const SkinContext& context) {
m_defaultCoverScaled = scaledCoverArt(m_defaultCover);
}
+void WCoverArt::slotReloadCoverArt() {
+ if (m_loadedTrack) {
+ CoverArtCache* pCache = CoverArtCache::instance();
+ if (pCache) {
+ pCache->requestGuessCover(m_loadedTrack);
+ }
+ }
+}
+
void WCoverArt::slotCoverArtSelected(const CoverArt& art) {
if (m_loadedTrack) {
// Will trigger slotTrackCoverArtUpdated().
diff --git a/src/widget/wcoverart.h b/src/widget/wcoverart.h
index 8ab44bfedd..aa0d7dd825 100644
--- a/src/widget/wcoverart.h
+++ b/src/widget/wcoverart.h
@@ -35,6 +35,7 @@ class WCoverArt : public QWidget, public WBaseWidget {
void slotCoverFound(const QObject* pRequestor, int requestReference,
const CoverInfo& info, QPixmap pixmap, bool fromCache);
void slotCoverArtSelected(const CoverArt& art);
+ void slotReloadCoverArt();
void slotTrackCoverArtUpdated();
protected:
diff --git a/src/widget/wcoverartlabel.cpp b/src/widget/wcoverartlabel.cpp
index 3325cf7e25..bdd15f9959 100644
--- a/src/widget/wcoverartlabel.cpp
+++ b/src/widget/wcoverartlabel.cpp
@@ -19,6 +19,8 @@ WCoverArtLabel::WCoverArtLabel(QWidget* parent)
this, SLOT(slotCoverMenu(QPoint)));
connect(m_pCoverMenu, SIGNAL(coverArtSelected(const CoverArt&)),
this, SIGNAL(coverArtSelected(const CoverArt&)));
+ connect(m_pCoverMenu, SIGNAL(reloadCoverArt()),
+ this, SIGNAL(reloadCoverArt()));
m_defaultCover = m_defaultCover.scaled(s_labelDisplaySize,
Qt::KeepAspectRatio,
diff --git a/src/widget/wcoverartlabel.h b/src/widget/wcoverartlabel.h
index ac1f062f2b..4b9452a973 100644
--- a/src/widget/wcoverartlabel.h
+++ b/src/widget/wcoverartlabel.h
@@ -19,6 +19,7 @@ class WCoverArtLabel : public QLabel {
signals:
void coverArtSelected(const CoverArt& art);
+ void reloadCoverArt();
protected:
void leaveEvent(QEvent*);
diff --git a/src/widget/wcoverartmenu.cpp b/src/widget/wcoverartmenu.cpp
index 4be49bf464..ca5f790e4c 100644
--- a/src/widget/wcoverartmenu.cpp
+++ b/src/widget/wcoverartmenu.cpp
@@ -28,7 +28,7 @@ void WCoverArtMenu::createActions() {
m_pReload = new QAction(tr("Reload from track/folder",
"reload cover art from track metadata or folder"), this);
- connect(m_pReload, SIGNAL(triggered()), this, SLOT(slotReload()));
+ connect(m_pReload, SIGNAL(triggered()), this, SIGNAL(reloadCoverArt()));
addAction(m_pReload);
}
@@ -90,12 +90,6 @@ void WCoverArtMenu::slotChange() {
emit(coverArtSelected(art));
}
-void WCoverArtMenu::slotReload() {
- CoverArt art = CoverArtUtils::guessCoverArt(m_pTrack);
- qDebug() << "WCoverArtMenu::slotReload emit" << art;
- emit(coverArtSelected(art));
-}
-
void WCoverArtMenu::slotUnset() {
CoverArt art;
art.info.type = CoverInfo::NONE;
diff --git a/src/widget/wcoverartmenu.h b/src/widget/wcoverartmenu.h
index 575aa073c2..798466d6e3 100644
--- a/src/widget/wcoverartmenu.h
+++ b/src/widget/wcoverartmenu.h
@@ -24,10 +24,10 @@ class WCoverArtMenu : public QMenu {
signals:
void coverArtSelected(const CoverArt& art);
+ void reloadCoverArt();
private slots:
void slotChange();
- void slotReload();
void slotUnset();
private:
diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp
index f6acf820e0..419003477f 100644
--- a/src/widget/wtracktableview.cpp
+++ b/src/widget/wtracktableview.cpp
@@ -83,6 +83,8 @@ WTrackTableView::WTrackTableView(QWidget * parent,
m_pCoverMenu->setTitle(tr("Cover Art"));
connect(m_pCoverMenu, SIGNAL(coverArtSelected(const CoverArt&)),
this, SLOT(slotCoverArtSelected(const CoverArt&)));
+ connect(m_pCoverMenu, SIGNAL(reloadCoverArt()),
+ this, SLOT(slotReloadCoverArt()));
// Disable editing
@@ -863,12 +865,22 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) {
m_pMenu->addAction(m_pReloadMetadataFromMusicBrainzAct);
}
- m_contextTrack = trackModel->getTrack(indices.at(0));
- m_pCoverMenu->setCoverArt(m_contextTrack, m_contextTrack->getCoverInfo());
- // TODO(rryan): support multiple selection. disable for now to indicate we
- // don't support it.
- m_pCoverMenu->setEnabled(indices.size() == 1);
+ // We load a single track to get the necessary context for the cover (we use
+ // last to be consistent with selectionChanged above).
+ QModelIndex last = indices.last();
+ CoverInfo info;
+ info.source = static_cast<CoverInfo::Source>(
+ last.sibling(last.row(), m_iCoverSourceColumn).data().toInt());
+ info.type = static_cast<CoverInfo::Type>(
+ last.sibling(last.row(), m_iCoverTypeColumn).data().toInt());
+ info.hash = last.sibling(last.row(), m_iCoverHashColumn).data().toUInt();
+ info.trackLocation = last.sibling(
+ last.row(), m_iTrackLocationColumn).data().toString();
+ info.coverLocation = last.sibling(
+ last.row(), m_iCoverLocationColumn).data().toString();
+ m_pCoverMenu->setCoverArt(TrackPointer(), info);
m_pMenu->addMenu(m_pCoverMenu);
+
// REMOVE and HIDE should not be at the first menu position to avoid accidental clicks
m_pMenu->addSeparator();
if (modelHasCapabilities(TrackModel::TRACKMODELCAPS_REMOVE)) {
@@ -1576,7 +1588,34 @@ void WTrackTableView::slotClearBeats() {
}
void WTrackTableView::slotCoverArtSelected(const CoverArt& art) {
- if (m_contextTrack) {
- m_contextTrack->setCoverArt(art);
+ TrackModel* trackModel = getTrackModel();
+ if (trackModel == NULL) {
+ return;
+ }
+ QModelIndexList selection = selectionModel()->selectedRows();
+ foreach (QModelIndex index, selection) {
+ TrackPointer pTrack = trackModel->getTrack(index);
+ if (pTrack) {
+ pTrack->setCoverArt(art);
+ }
+ }
+}
+
+void WTrackTableView::slotReloadCoverArt() {
+ TrackModel* trackModel = getTrackModel();
+ if (trackModel == NULL) {
+ return;
+ }
+ QList<TrackPointer> selectedTracks;
+ QModelIndexList selection = selectionModel()->selectedRows();
+ foreach (QModelIndex index, selection) {
+ TrackPointer pTrack = trackModel->getTrack(index);
+ if (pTrack) {
+ selectedTracks.append(pTrack);
+ }
+ }
+ CoverArtCache* pCache = CoverArtCache::instance();
+ if (pCache) {
+ pCache->requestGuessCovers(selectedTracks);
}
}
diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h
index fc835575e7..5fd0ed1bc8 100644
--- a/src/widget/wtracktableview.h
+++ b/src/widget/wtracktableview.h
@@ -75,6 +75,7 @@ class WTrackTableView : public WLibraryTableView {
void slotGuiTick50ms(double);
void slotScrollValueChanged(int);
void slotCoverArtSelected(const CoverArt& art);
+ void slotReloadCoverArt();
private:
void sendToAutoDJ(bool bTop);
@@ -163,8 +164,6 @@ class WTrackTableView : public WLibraryTableView {
int m_iCoverColumn; // visible cover art
int m_iTrackLocationColumn;
- TrackPointer m_contextTrack;
-
// Control the delay to load a cover art.
qint64 m_lastUserActionNanos;
bool m_loadCachedOnly;