diff options
author | Jan Holthuis <jan.holthuis@ruhr-uni-bochum.de> | 2020-04-06 14:33:05 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-06 14:33:05 +0200 |
commit | 6882798655322c17b163979ff190cc775afd1acc (patch) | |
tree | dca32735b80e1f092aff47cde912105f555e9a2c | |
parent | 82577027821538aaaac493108d5713f6e15a89e1 (diff) | |
parent | cef6fbebaf424563621ba8f6ab23d291bc34d6cf (diff) |
Merge pull request #2538 from uklotzde/basetracktablemodel
Refactoring: Extract BaseTrackTableModel + BaseCoverArtDelegate
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 |