summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Holthuis <jan.holthuis@ruhr-uni-bochum.de>2020-04-06 14:33:05 +0200
committerGitHub <noreply@github.com>2020-04-06 14:33:05 +0200
commit6882798655322c17b163979ff190cc775afd1acc (patch)
treedca32735b80e1f092aff47cde912105f555e9a2c
parent82577027821538aaaac493108d5713f6e15a89e1 (diff)
parentcef6fbebaf424563621ba8f6ab23d291bc34d6cf (diff)
Merge pull request #2538 from uklotzde/basetracktablemodel
Refactoring: Extract BaseTrackTableModel + BaseCoverArtDelegate
-rw-r--r--CMakeLists.txt2
-rw-r--r--build/depends.py2
-rw-r--r--src/library/banshee/bansheeplaylistmodel.cpp65
-rw-r--r--src/library/banshee/bansheeplaylistmodel.h11
-rw-r--r--src/library/basecoverartdelegate.cpp143
-rw-r--r--src/library/basecoverartdelegate.h75
-rw-r--r--src/library/baseexternalplaylistmodel.cpp35
-rw-r--r--src/library/baseexternalplaylistmodel.h3
-rw-r--r--src/library/baseexternaltrackmodel.cpp35
-rw-r--r--src/library/baseexternaltrackmodel.h4
-rw-r--r--src/library/basesqltablemodel.cpp767
-rw-r--r--src/library/basesqltablemodel.h104
-rw-r--r--src/library/basetrackcache.cpp6
-rw-r--r--src/library/basetrackcache.h2
-rw-r--r--src/library/basetracktablemodel.cpp795
-rw-r--r--src/library/basetracktablemodel.h214
-rw-r--r--src/library/coverartdelegate.cpp197
-rw-r--r--src/library/coverartdelegate.h64
-rw-r--r--src/library/dao/autodjcratesdao.cpp4
-rw-r--r--src/library/dao/trackdao.cpp2
-rw-r--r--src/library/dao/trackdao.h1
-rw-r--r--src/library/tableitemdelegate.cpp45
-rw-r--r--src/library/tableitemdelegate.h16
-rw-r--r--src/library/trackcollection.cpp44
-rw-r--r--src/library/trackcollection.h8
25 files changed, 1618 insertions, 1026 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5053489dca..0d8c5f9385 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -342,12 +342,14 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/library/banshee/bansheedbconnection.cpp
src/library/banshee/bansheefeature.cpp
src/library/banshee/bansheeplaylistmodel.cpp
+ src/library/basecoverartdelegate.cpp
src/library/baseexternallibraryfeature.cpp
src/library/baseexternalplaylistmodel.cpp
src/library/baseexternaltrackmodel.cpp
src/library/baseplaylistfeature.cpp
src/library/basesqltablemodel.cpp
src/library/basetrackcache.cpp
+ src/library/basetracktablemodel.cpp
src/library/bpmdelegate.cpp
src/library/browse/browsefeature.cpp
src/library/browse/browsetablemodel.cpp
diff --git a/build/depends.py b/build/depends.py
index cc6572f845..b68c7f85cd 100644
--- a/build/depends.py
+++ b/build/depends.py
@@ -1027,6 +1027,7 @@ class MixxxCore(Feature):
"src/library/externaltrackcollection.cpp",
"src/library/basesqltablemodel.cpp",
"src/library/basetrackcache.cpp",
+ "src/library/basetracktablemodel.cpp",
"src/library/columncache.cpp",
"src/library/librarytablemodel.cpp",
"src/library/searchquery.cpp",
@@ -1121,6 +1122,7 @@ class MixxxCore(Feature):
"src/library/bpmdelegate.cpp",
"src/library/previewbuttondelegate.cpp",
"src/library/colordelegate.cpp",
+ "src/library/basecoverartdelegate.cpp",
"src/library/coverartdelegate.cpp",
"src/library/locationdelegate.cpp",
"src/library/tableitemdelegate.cpp",
diff --git a/src/library/banshee/bansheeplaylistmodel.cpp b/src/library/banshee/bansheeplaylistmodel.cpp
index 68c52afa6d..d1b125a57e 100644
--- a/src/library/banshee/bansheeplaylistmodel.cpp
+++ b/src/library/banshee/bansheeplaylistmodel.cpp
@@ -221,13 +221,6 @@ void BansheePlaylistModel::setTableModel(int playlistId) {
setSort(defaultSortColumn(), defaultSortOrder());
}
-bool BansheePlaylistModel::setData(const QModelIndex& index, const QVariant& value, int role) {
- Q_UNUSED(index);
- Q_UNUSED(value);
- Q_UNUSED(role);
- return false;
-}
-
TrackModel::CapabilitiesFlags BansheePlaylistModel::getCapabilities() const {
return TRACKMODELCAPS_NONE
| TRACKMODELCAPS_ADDTOPLAYLIST
@@ -238,65 +231,23 @@ TrackModel::CapabilitiesFlags BansheePlaylistModel::getCapabilities() const {
}
Qt::ItemFlags BansheePlaylistModel::flags(const QModelIndex &index) const {
- return readWriteFlags(index);
-}
-
-Qt::ItemFlags BansheePlaylistModel::readWriteFlags(const QModelIndex &index) const {
- if (!index.isValid()) {
- return Qt::ItemIsEnabled;
- }
-
- Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index);
-
- // Enable dragging songs from this data model to elsewhere (like the waveform
- // widget to load a track into a Player).
- defaultFlags |= Qt::ItemIsDragEnabled;
-
- return defaultFlags;
-}
-
-Qt::ItemFlags BansheePlaylistModel::readOnlyFlags(const QModelIndex &index) const
-{
- Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index);
- if (!index.isValid())
- return Qt::ItemIsEnabled;
-
- //Enable dragging songs from this data model to elsewhere (like the waveform widget to
- //load a track into a Player).
- defaultFlags |= Qt::ItemIsDragEnabled;
-
- return defaultFlags;
+ return readOnlyFlags(index);
}
void BansheePlaylistModel::tracksChanged(QSet<TrackId> trackIds) {
Q_UNUSED(trackIds);
}
-void BansheePlaylistModel::trackLoaded(QString group, TrackPointer pTrack) {
- if (group == m_previewDeckGroup) {
- // If there was a previously loaded track, refresh its rows so the
- // preview state will update.
- if (m_previewDeckTrackId.isValid()) {
- const int numColumns = columnCount();
- QLinkedList<int> rows = getTrackRows(m_previewDeckTrackId);
- m_previewDeckTrackId = TrackId(); // invalidate
- foreach (int row, rows) {
- QModelIndex left = index(row, 0);
- QModelIndex right = index(row, numColumns);
- emit dataChanged(left, right);
- }
- }
- if (pTrack) {
- for (int row = 0; row < rowCount(); ++row) {
- const QUrl rowUrl(getFieldString(index(row, 0), CLM_URI));
- if (TrackFile::fromUrl(rowUrl) == pTrack->getFileInfo()) {
- m_previewDeckTrackId =
- TrackId(getFieldVariant(index(row, 0), CLM_VIEW_ORDER));
- break;
- }
+TrackId BansheePlaylistModel::doGetTrackId(const TrackPointer& pTrack) const {
+ if (pTrack) {
+ for (int row = 0; row < rowCount(); ++row) {
+ const QUrl rowUrl(getFieldString(index(row, 0), CLM_URI));
+ if (TrackFile::fromUrl(rowUrl) == pTrack->getFileInfo()) {
+ return TrackId(getFieldVariant(index(row, 0), CLM_VIEW_ORDER));
}
}
}
+ return TrackId();
}
QVariant BansheePlaylistModel::getFieldVariant(const QModelIndex& index,
diff --git a/src/library/banshee/bansheeplaylistmodel.h b/src/library/banshee/bansheeplaylistmodel.h
index 6e7149a710..d6cad06cf5 100644
--- a/src/library/banshee/bansheeplaylistmodel.h
+++ b/src/library/banshee/bansheeplaylistmodel.h
@@ -28,19 +28,12 @@ class BansheePlaylistModel : public BaseSqlTableModel {
Qt::ItemFlags flags(const QModelIndex &index) const final;
CapabilitiesFlags getCapabilities() const final;
- bool setData(const QModelIndex& index, const QVariant& value, int role=Qt::EditRole) final;
-
- protected:
- // Use this if you want a model that is read-only.
- Qt::ItemFlags readOnlyFlags(const QModelIndex &index) const final;
- // Use this if you want a model that can be changed
- Qt::ItemFlags readWriteFlags(const QModelIndex &index) const final;
-
private slots:
void tracksChanged(QSet<TrackId> trackIds);
- void trackLoaded(QString group, TrackPointer pTrack);
private:
+ TrackId doGetTrackId(const TrackPointer& pTrack) const final;
+
QString getFieldString(const QModelIndex& index, const QString& fieldName) const;
QVariant getFieldVariant(const QModelIndex& index, const QString& fieldName) const;
void dropTempTable();
diff --git a/src/library/basecoverartdelegate.cpp b/src/library/basecoverartdelegate.cpp
new file mode 100644
index 0000000000..afb31d03b3
--- /dev/null
+++ b/src/library/basecoverartdelegate.cpp
@@ -0,0 +1,143 @@
+#include "library/coverartdelegate.h"
+
+#include <QPainter>
+#include <algorithm>
+
+#include "library/coverartcache.h"
+#include "library/dao/trackschema.h"
+#include "library/trackmodel.h"
+#include "util/logger.h"
+#include "widget/wlibrarytableview.h"
+
+namespace {
+
+const mixxx::Logger kLogger("BaseCoverArtDelegate");
+
+inline TrackModel* asTrackModel(
+ QTableView* pTableView) {
+ auto* pTrackModel =
+ dynamic_cast<TrackModel*>(pTableView->model());
+ DEBUG_ASSERT(pTrackModel);
+ return pTrackModel;
+}
+
+} // anonymous namespace
+
+BaseCoverArtDelegate::BaseCoverArtDelegate(QTableView* parent)
+ : TableItemDelegate(parent),
+ m_pTrackModel(asTrackModel(parent)),
+ m_pCache(CoverArtCache::instance()),
+ m_inhibitLazyLoading(false) {
+ if (m_pCache) {
+ connect(m_pCache,
+ &CoverArtCache::coverFound,
+ this,
+ &BaseCoverArtDelegate::slotCoverFound);
+ } else {
+ kLogger.warning()
+ << "Caching of cover art is not available";
+ }
+}
+
+void BaseCoverArtDelegate::emitRowsChanged(
+ QList<int>&& rows) {
+ if (rows.isEmpty()) {
+ return;
+ }
+ // Sort in ascending order...
+ std::sort(rows.begin(), rows.end());
+ // ...and then deduplicate...
+ rows.erase(std::unique(rows.begin(), rows.end()), rows.end());
+ // ...before emitting the signal.
+ DEBUG_ASSERT(!rows.isEmpty());
+ emit rowsChanged(std::move(rows));
+}
+
+void BaseCoverArtDelegate::slotInhibitLazyLoading(
+ bool inhibitLazyLoading) {
+ m_inhibitLazyLoading = inhibitLazyLoading;
+ if (m_inhibitLazyLoading || m_cacheMissRows.isEmpty()) {
+ return;
+ }
+ // If we can request non-cache covers now, request updates
+ // for all rows that were cache misses since the last time.
+ auto staleRows = m_cacheMissRows;
+ // Reset the member variable before mutating the aggregated
+ // rows list (-> implicit sharing) and emitting a signal that
+ // in turn may trigger new signals for BaseCoverArtDelegate!
+ m_cacheMissRows = QList<int>();
+ emitRowsChanged(std::move(staleRows));
+}
+
+void BaseCoverArtDelegate::slotCoverFound(
+ const QObject* pRequestor,
+ const CoverInfo& coverInfo,
+ const QPixmap& pixmap,
+ mixxx::cache_key_t requestedImageHash,
+ bool coverInfoUpdated) {
+ Q_UNUSED(pixmap);
+ if (pRequestor != this) {
+ return;
+ }
+ if (coverInfoUpdated) {
+ const auto pTrack =
+ loadTrackByLocation(coverInfo.trackLocation);
+ if (pTrack) {
+ kLogger.info()
+ << "Updating cover info of track"
+ << coverInfo.trackLocation;
+ pTrack->setCoverInfo(coverInfo);
+ }
+ }
+ QList<int> refreshRows = m_pendingCacheRows.values(requestedImageHash);
+ m_pendingCacheRows.remove(requestedImageHash);
+ emitRowsChanged(std::move(refreshRows));
+}
+
+TrackPointer BaseCoverArtDelegate::loadTrackByLocation(
+ const QString& trackLocation) const {
+ VERIFY_OR_DEBUG_ASSERT(m_pTrackModel) {
+ return TrackPointer();
+ }
+ return m_pTrackModel->getTrackByRef(
+ TrackRef::fromFileInfo(trackLocation));
+}
+
+void BaseCoverArtDelegate::paintItem(
+ QPainter* painter,
+ const QStyleOptionViewItem& option,
+ const QModelIndex& index) const {
+ paintItemBackground(painter, option, index);
+
+ CoverInfo coverInfo = coverInfoForIndex(index);
+ if (CoverImageUtils::isValidHash(coverInfo.hash)) {
+ VERIFY_OR_DEBUG_ASSERT(m_pCache) {
+ return;
+ }
+ const double scaleFactor =
+ getDevicePixelRatioF(static_cast<QWidget*>(parent()));
+ QPixmap pixmap = m_pCache->tryLoadCover(
+ this,
+ coverInfo,
+ option.rect.width() * scaleFactor,
+ m_inhibitLazyLoading ? CoverArtCache::Loading::CachedOnly : CoverArtCache::Loading::Default);
+ if (pixmap.isNull()) {
+ // Cache miss
+ if (m_inhibitLazyLoading) {
+ // We are requesting cache-only covers and got a cache
+ // miss. Record this row so that when we switch to requesting
+ // non-cache we can request an update.
+ m_cacheMissRows.append(index.row());
+ } else {
+ // If we asked for a non-cache image and got a null pixmap,
+ // then our request was queued.
+ m_pendingCacheRows.insertMulti(coverInfo.hash, index.row());
+ }
+ } else {
+ // Cache hit
+ pixmap.setDevicePixelRatio(scaleFactor);
+ painter->drawPixmap(option.rect.topLeft(), pixmap);
+ return;
+ }
+ }
+}
diff --git a/src/library/basecoverartdelegate.h b/src/library/basecoverartdelegate.h
new file mode 100644
index 0000000000..cf7745705c
--- /dev/null
+++ b/src/library/basecoverartdelegate.h
@@ -0,0 +1,75 @@
+#pragma once
+
+#include <QHash>
+#include <QList>
+#include <QTableView>
+
+#include "library/tableitemdelegate.h"
+#include "track/track.h"
+#include "util/cache.h"
+
+class CoverArtCache;
+class TrackModel;
+
+class BaseCoverArtDelegate : public TableItemDelegate {
+ Q_OBJECT
+
+ public:
+ explicit BaseCoverArtDelegate(
+ QTableView* parent);
+ ~BaseCoverArtDelegate() override = default;
+
+ void paintItem(
+ QPainter* painter,
+ const QStyleOptionViewItem& option,
+ const QModelIndex& index) const final;
+
+ signals:
+ // Sent when rows need to be refreshed
+ void rowsChanged(
+ QList<int> rows);
+
+ public slots:
+ // Advise the delegate to temporarily inhibit lazy loading
+ // of cover images and to only display those cover images
+ // that have already been cached. Otherwise only the solid
+ // (background) color is painted.
+ //
+ // It is useful to handle cases when the user scroll down
+ // very fast or when they hold an arrow key. In thise case
+ // it is NOT desirable to start multiple expensive file
+ // system operations in worker threads for loading and
+ // scaling cover images that are not even displayed after
+ // scrolling beyond them.
+ void slotInhibitLazyLoading(
+ bool inhibitLazyLoading);
+
+ private slots:
+ void slotCoverFound(
+ const QObject* pRequestor,
+ const CoverInfo& coverInfo,
+ const QPixmap& pixmap,
+ mixxx::cache_key_t requestedImageHash,
+ bool coverInfoUpdated);
+
+ protected:
+ TrackModel* const m_pTrackModel;
+
+ private:
+ void emitRowsChanged(
+ QList<int>&& rows);
+
+ TrackPointer loadTrackByLocation(
+ const QString& trackLocation) const;
+
+ virtual CoverInfo coverInfoForIndex(
+ const QModelIndex& index) const = 0;
+
+ CoverArtCache* const m_pCache;
+ bool m_inhibitLazyLoading;
+
+ // We need to record rows in paint() (which is const) so
+ // these are marked mutable.
+ mutable QList<int> m_cacheMissRows;
+ mutable QHash<mixxx::cache_key_t, int> m_pendingCacheRows;
+};
diff --git a/src/library/baseexternalplaylistmodel.cpp b/src/library/baseexternalplaylistmodel.cpp
index fd560fbc59..0a2b17807c 100644
--- a/src/library/baseexternalplaylistmodel.cpp
+++ b/src/library/baseexternalplaylistmodel.cpp
@@ -145,34 +145,19 @@ void BaseExternalPlaylistModel::setPlaylist(QString playlist_path) {
setSearch("");
}
-void BaseExternalPlaylistModel::trackLoaded(QString group, TrackPointer pTrack) {
- if (group == m_previewDeckGroup) {
- // If there was a previously loaded track, refresh its rows so the
- // preview state will update.
- if (m_previewDeckTrackId.isValid()) {
- const int numColumns = columnCount();
- QLinkedList<int> rows = getTrackRows(m_previewDeckTrackId);
- m_previewDeckTrackId = TrackId(); // invalidate
- foreach (int row, rows) {
- QModelIndex left = index(row, 0);
- QModelIndex right = index(row, numColumns);
- emit dataChanged(left, right);
- }
- }
- if (pTrack) {
- // The external table has foreign Track IDs, so we need to compare
- // by location
- for (int row = 0; row < rowCount(); ++row) {
- QString nativeLocation = index(row, fieldIndex("location")).data().toString();
- QString location = QDir::fromNativeSeparators(nativeLocation);
- if (location == pTrack->getLocation()) {
- m_previewDeckTrackId = TrackId(index(row, 0).data());
- //Debug() << "foreign track id" << m_previewDeckTrackId;
- break;
- }
+TrackId BaseExternalPlaylistModel::doGetTrackId(const TrackPointer& pTrack) const {
+ if (pTrack) {
+ // The external table has foreign Track IDs, so we need to compare
+ // by location
+ for (int row = 0; row < rowCount(); ++row) {
+ QString nativeLocation = index(row, fieldIndex("location")).data().toString();
+ QString location = QDir::fromNativeSeparators(nativeLocation);
+ if (location == pTrack->getLocation()) {
+ return TrackId(index(row, 0).data());
}
}
}
+ return TrackId();
}
TrackModel::CapabilitiesFlags BaseExternalPlaylistModel::getCapabilities() const {
diff --git a/src/library/baseexternalplaylistmodel.h b/src/library/baseexternalplaylistmodel.h
index 8d0321ff9c..b1b19e9f00 100644
--- a/src/library/baseexternalplaylistmodel.h
+++ b/src/library/baseexternalplaylistmodel.h
@@ -28,10 +28,11 @@ class BaseExternalPlaylistModel : public BaseSqlTableModel {
TrackId getTrackId(const QModelIndex& index) const override;
bool isColumnInternal(int column) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
- void trackLoaded(QString group, TrackPointer pTrack) override;
CapabilitiesFlags getCapabilities() const override;
private:
+ TrackId doGetTrackId(const TrackPointer& pTrack) const override;
+
QString m_playlistsTable;
QString m_playlistTracksTable;
QSharedPointer<BaseTrackCache> m_trackSource;
diff --git a/src/library/baseexternaltrackmodel.cpp b/src/library/baseexternaltrackmodel.cpp
index 6d4d552522..68f2aa8794 100644
--- a/src/library/baseexternaltrackmodel.cpp
+++ b/src/library/baseexternaltrackmodel.cpp
@@ -88,34 +88,19 @@ TrackId BaseExternalTrackModel::getTrackId(const QModelIndex& index) const {
}
}
-void BaseExternalTrackModel::trackLoaded(QString group, TrackPointer pTrack) {
- if (group == m_previewDeckGroup) {
- // If there was a previously loaded track, refresh its rows so the
- // preview state will update.
- if (m_previewDeckTrackId.isValid()) {
- const int numColumns = columnCount();
- QLinkedList<int> rows = getTrackRows(m_previewDeckTrackId);
- m_previewDeckTrackId = TrackId(); // invalidate
- foreach (int row, rows) {
- QModelIndex left = index(row, 0);
- QModelIndex right = index(row, numColumns);
- emit dataChanged(left, right);
- }
- }
- if (pTrack) {
- // The external table has foreign Track IDs, so we need to compare
- // by location
- for (int row = 0; row < rowCount(); ++row) {
- QString nativeLocation = index(row, fieldIndex("location")).data().toString();
- QString location = QDir::fromNativeSeparators(nativeLocation);
- if (location == pTrack->getLocation()) {
- m_previewDeckTrackId = TrackId(index(row, 0).data());
- //qDebug() << "foreign track id" << m_previewDeckTrackId;
- break;
- }
+TrackId BaseExternalTrackModel::doGetTrackId(const TrackPointer& pTrack) const {
+ if (pTrack) {
+ // The external table has foreign Track IDs, so we need to compare
+ // by location
+ for (int row = 0; row < rowCount(); ++row) {
+ QString nativeLocation = index(row, fieldIndex("location")).data().toString();
+ QString location = QDir::fromNativeSeparators(nativeLocation);
+ if (location == pTrack->getLocation()) {
+ return TrackId(index(row, 0).data());
}
}
}
+ return TrackId();
}
bool BaseExternalTrackModel::isColumnInternal(int column) {
diff --git a/src/library/baseexternaltrackmodel.h b/src/library/baseexternaltrackmodel.h
index 16db84caab..23ed68092c 100644
--- a/src/library/baseexternaltrackmodel.h
+++ b/src/library/baseexternaltrackmodel.h
@@ -23,9 +23,11 @@ class BaseExternalTrackModel : public BaseSqlTableModel {
CapabilitiesFlags getCapabilities() const override;
TrackId getTrackId(const QModelIndex& index) const override;
TrackPointer getTrack(const QModelIndex& index) const override;
- void trackLoaded(QString group, TrackPointer pTrack) override;
bool isColumnInternal(int column) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
+
+ private:
+ TrackId doGetTrackId(const TrackPointer& pTrack) const override;
};
#endif /* BASEEXTERNALTRACKMODEL_H */
diff --git a/src/library/basesqltablemodel.cpp b/src/library/basesqltablemodel.cpp
index a45fa51965..2c95384653 100644
--- a/src/library/basesqltablemodel.cpp
+++ b/src/library/basesqltablemodel.cpp
@@ -1,31 +1,25 @@
// Created by RJ Ryan (rryan@mit.edu) 1/29/2010
-#include <algorithm>
-#include <QtDebug>
-#include <QUrl>
-
#include "library/basesqltablemodel.h"
-#include "library/bpmdelegate.h"
-#include "library/colordelegate.h"
+#include <QUrl>
+#include <QtDebug>
+#include <algorithm>
+
#include "library/coverartdelegate.h"
-#include "library/locationdelegate.h"
-#include "library/previewbuttondelegate.h"
+#include "library/dao/trackschema.h"
+#include "library/queryutil.h"
+#include "library/starrating.h"
#include "library/trackcollection.h"
#include "library/trackcollectionmanager.h"
-#include "library/stardelegate.h"
-#include "library/starrating.h"
-#include "library/queryutil.h"
#include "mixer/playermanager.h"
-#include "mixer/playerinfo.h"
#include "track/keyutils.h"
#include "track/trackmetadata.h"
+#include "util/assert.h"
#include "util/db/dbconnection.h"
#include "util/duration.h"
-#include "util/assert.h"
#include "util/performancetimer.h"
#include "util/platform.h"
-#include "widget/wlibrarytableview.h"
namespace {
@@ -40,95 +34,36 @@ const int kMaxSortColumns = 3;
// Constant for getModelSetting(name)
const QString COLUMNS_SORTING = QStringLiteral("ColumnsSorting");
-// Alpha value for row color background (range 0 - 255)
-constexpr int kTrackColorRowBackgroundOpacity = 0x20; // 12.5% opacity
+const QString kEmptyString = QStringLiteral("");
} // anonymous namespace
-BaseSqlTableModel::BaseSqlTableModel(QObject* pParent,
- TrackCollectionManager* pTrackCollectionManager,
- const char* settingsNamespace)
- : QAbstractTableModel(pParent),
- TrackModel(pTrackCollectionManager->internalCollection()->database(), settingsNamespace),
+BaseSqlTableModel::BaseSqlTableModel(
+ QObject* parent,
+ TrackCollectionManager* pTrackCollectionManager,
+ const char* settingsNamespace)
+ : BaseTrackTableModel(
+ settingsNamespace,
+ pTrackCollectionManager,
+ parent),
m_pTrackCollectionManager(pTrackCollectionManager),
m_database(pTrackCollectionManager->internalCollection()->database()),
- m_previewDeckGroup(PlayerManager::groupForPreviewDeck(0)),
m_bInitialized(false),
- m_currentSearch("") {
- connect(&PlayerInfo::instance(),
- &PlayerInfo::trackLoaded,
- this,
- &BaseSqlTableModel::trackLoaded);
- connect(&pTrackCollectionManager->internalCollection()->getTrackDAO(),
- &TrackDAO::forceModelUpdate,
- this,
- &BaseSqlTableModel::select);
- // TODO(rryan): This is a virtual function call from a constructor.
- trackLoaded(m_previewDeckGroup, PlayerInfo::instance().getTrackInfo(m_previewDeckGroup));
+ m_currentSearch(kEmptyString) {
}
BaseSqlTableModel::~BaseSqlTableModel() {
}
-void BaseSqlTableModel::initHeaderData() {
- // Set the column heading labels, rename them for translations and have
- // proper capitalization
-
- // TODO(owilliams): Clean this up to make it readable.
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_TIMESPLAYED,
- tr("Played"), 50);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_ARTIST,
- tr("Artist"), 200);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_TITLE,
- tr("Title"), 300);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_ALBUM,
- tr("Album"), 200);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_ALBUMARTIST,
- tr("Album Artist"), 100);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_GENRE,
- tr("Genre"), 100);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_COMPOSER,
- tr("Composer"), 50);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_GROUPING,
- tr("Grouping"), 10);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_YEAR,
- tr("Year"), 40);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_FILETYPE,
- tr("Type"), 50);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_NATIVELOCATION,
- tr("Location"), 100);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_COMMENT,
- tr("Comment"), 250);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_DURATION,
- tr("Duration"), 70);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_RATING,
- tr("Rating"), 100);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_BITRATE,
- tr("Bitrate"), 50);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_BPM,
- tr("BPM"), 70);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_TRACKNUMBER,
- tr("Track #"), 10);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_DATETIMEADDED,
- tr("Date Added"), 90);
+void BaseSqlTableModel::initHeaderProperties() {
+ BaseTrackTableModel::initHeaderProperties();
+ // Add playlist columns
setHeaderProperties(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION,
- tr("#"), 30);
+ tr("#"),
+ 30);
setHeaderProperties(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_DATETIMEADDED,
- tr("Timestamp"), 80);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_KEY,
- tr("Key"), 50);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_BPM_LOCK,
- tr("BPM Lock"), 10);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_PREVIEW,
- tr("Preview"), 50);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_COVERART,
- tr("Cover Art"), 90);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_COLOR,
- tr("Color"), 10);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_REPLAYGAIN,
- tr("ReplayGain"), 50);
- setHeaderProperties(ColumnCache::COLUMN_LIBRARYTABLE_SAMPLERATE,
- tr("Samplerate"), 50);
+ tr("Timestamp"),
+ 80);
}
void BaseSqlTableModel::initSortColumnMapping() {
@@ -168,79 +103,6 @@ void BaseSqlTableModel::initSortColumnMapping() {
}
}
-void BaseSqlTableModel::setHeaderProperties(
- ColumnCache::Column column, QString title, int defaultWidth) {
- int fi = fieldIndex(column);
- setHeaderData(fi, Qt::Horizontal, m_tableColumnCache.columnName(column),
- TrackModel::kHeaderNameRole);
- setHeaderData(fi, Qt::Horizontal, title, Qt::DisplayRole);
- setHeaderData(fi, Qt::Horizontal, defaultWidth, TrackModel::kHeaderWidthRole);
-}
-
-bool BaseSqlTableModel::setHeaderData(int section, Qt::Orientation orientation,
- const QVariant &value, int role) {
- int numColumns = columnCount();
- if (section < 0 || section >= numColumns) {
- return false;
- }
-
- if (orientation != Qt::Horizontal) {
- // We only care about horizontal headers.
- return false;
- }
-
- if (m_headerInfo.size() != numColumns) {
- m_headerInfo.resize(numColumns);
- }
-
- m_headerInfo[section][role] = value;
- emit headerDataChanged(orientation, section, section);
- return true;
-}
-
-QVariant BaseSqlTableModel::headerData(int section, Qt::Orientation orientation,
- int role) const {
- if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
- QVariant headerValue = m_headerInfo.value(section).value(role);
- if (!headerValue.isValid()) {
- // Try EditRole if DisplayRole wasn't present
- headerValue = m_headerInfo.value(section).value(Qt::EditRole);
- }
- if (!headerValue.isValid()) {
- headerValue = QVariant(section).toString();
- }
- return headerValue;
- } else if (role == TrackModel::kHeaderWidthRole && orientation == Qt::Horizontal) {
- QVariant widthValue = m_headerInfo.value(section).value(role);
- if (!widthValue.isValid()) {
- return 50;
- }
- return widthValue;
- } else if (role == TrackModel::kHeaderNameRole && orientation == Qt::Horizontal) {
- return m_headerInfo.value(section).value(role);
- } else if (role == Qt::ToolTipRole && orientation == Qt::Horizontal) {
- QVariant tooltip = m_headerInfo.value(section).value(role);
- if (tooltip.isValid()) return tooltip;
- }
- return QAbstractTableModel::headerData(section, orientation, role);
-}
-
-
-bool BaseSqlTableModel::isColumnHiddenByDefault(int column) {
- if ((column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COMPOSER)) ||
- (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_TRACKNUMBER)) ||
- (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_YEAR)) ||
- (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_GROUPING)) ||
- (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_NATIVELOCATION)) ||
- (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ALBUMARTIST)) ||
- (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_REPLAYGAIN)) ||
- (column == fieldIndex(ColumnCache