diff --git a/src/models/abstractmediaproxymodel.cpp b/src/models/abstractmediaproxymodel.cpp index c4ab099c..33fbea0f 100644 --- a/src/models/abstractmediaproxymodel.cpp +++ b/src/models/abstractmediaproxymodel.cpp @@ -1,112 +1,141 @@ /* SPDX-FileCopyrightText: 2016 (c) Matthieu Gallien SPDX-FileCopyrightText: 2017 (c) Alexander Stippich SPDX-License-Identifier: LGPL-3.0-or-later */ #include "abstractmediaproxymodel.h" #include "mediaplaylistproxymodel.h" #include +#include +#include AbstractMediaProxyModel::AbstractMediaProxyModel(QObject *parent) : QSortFilterProxyModel(parent) { setFilterCaseSensitivity(Qt::CaseInsensitive); mThreadPool.setMaxThreadCount(1); } AbstractMediaProxyModel::~AbstractMediaProxyModel() = default; QString AbstractMediaProxyModel::filterText() const { return mFilterText; } int AbstractMediaProxyModel::filterRating() const { return mFilterRating; } void AbstractMediaProxyModel::setFilterText(const QString &filterText) { QWriteLocker writeLocker(&mDataLock); if (mFilterText == filterText) return; mFilterText = filterText; mFilterExpression.setPattern(mFilterText); mFilterExpression.setPatternOptions(QRegularExpression::CaseInsensitiveOption); mFilterExpression.optimize(); invalidate(); Q_EMIT filterTextChanged(mFilterText); } void AbstractMediaProxyModel::setFilterRating(int filterRating) { QWriteLocker writeLocker(&mDataLock); if (mFilterRating == filterRating) { return; } mFilterRating = filterRating; invalidate(); Q_EMIT filterRatingChanged(filterRating); } bool AbstractMediaProxyModel::sortedAscending() const { return sortOrder() ? false : true; } MediaPlayListProxyModel *AbstractMediaProxyModel::playList() const { return mPlayList; } void AbstractMediaProxyModel::sortModel(Qt::SortOrder order) { this->sort(0, order); Q_EMIT sortedAscendingChanged(); } void AbstractMediaProxyModel::setPlayList(MediaPlayListProxyModel *playList) { disconnectPlayList(); if (mPlayList == playList) { return; } mPlayList = playList; Q_EMIT playListChanged(); connectPlayList(); } void AbstractMediaProxyModel::disconnectPlayList() { if (mPlayList) { disconnect(this, &AbstractMediaProxyModel::entriesToEnqueue, mPlayList, static_cast(&MediaPlayListProxyModel::enqueue)); } } void AbstractMediaProxyModel::connectPlayList() { if (mPlayList) { connect(this, &AbstractMediaProxyModel::entriesToEnqueue, mPlayList, static_cast(&MediaPlayListProxyModel::enqueue)); } } +void AbstractMediaProxyModel::genericEnqueueToPlayList(ElisaUtils::PlayListEnqueueMode enqueueMode, + ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay) +{ + QtConcurrent::run(&mThreadPool, [=] () { + QReadLocker locker(&mDataLock); + auto allData = DataTypes::EntryDataList{}; + allData.reserve(rowCount()); + for (int rowIndex = 0, maxRowCount = rowCount(); rowIndex < maxRowCount; ++rowIndex) { + auto currentIndex = index(rowIndex, 0); + + allData.push_back(DataTypes::EntryData{data(currentIndex, DataTypes::FullDataRole).value(), + data(currentIndex, Qt::DisplayRole).toString(), {}}); + } + Q_EMIT entriesToEnqueue(allData, enqueueMode, triggerPlay); + }); +} + +void AbstractMediaProxyModel::enqueueToPlayList() +{ + genericEnqueueToPlayList(ElisaUtils::AppendPlayList, ElisaUtils::DoNotTriggerPlay); +} + +void AbstractMediaProxyModel::replaceAndPlayOfPlayList() +{ + genericEnqueueToPlayList(ElisaUtils::ReplacePlayList, ElisaUtils::TriggerPlay); +} + #include "moc_abstractmediaproxymodel.cpp" diff --git a/src/models/abstractmediaproxymodel.h b/src/models/abstractmediaproxymodel.h index fd7d5402..c8c85351 100644 --- a/src/models/abstractmediaproxymodel.h +++ b/src/models/abstractmediaproxymodel.h @@ -1,104 +1,113 @@ /* SPDX-FileCopyrightText: 2016 (c) Matthieu Gallien SPDX-FileCopyrightText: 2017 (c) Alexander Stippich SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef ABSTRACTMEDIAPROXYMODEL_H #define ABSTRACTMEDIAPROXYMODEL_H #include "elisaLib_export.h" #include "elisautils.h" #include "datatypes.h" #include #include #include #include class MediaPlayListProxyModel; class ELISALIB_EXPORT AbstractMediaProxyModel : public QSortFilterProxyModel { Q_OBJECT Q_PROPERTY(QString filterText READ filterText WRITE setFilterText NOTIFY filterTextChanged) Q_PROPERTY(int filterRating READ filterRating WRITE setFilterRating NOTIFY filterRatingChanged) Q_PROPERTY(bool sortedAscending READ sortedAscending NOTIFY sortedAscendingChanged) Q_PROPERTY(MediaPlayListProxyModel* playList READ playList WRITE setPlayList NOTIFY playListChanged) public: explicit AbstractMediaProxyModel(QObject *parent = nullptr); ~AbstractMediaProxyModel() override; QString filterText() const; int filterRating() const; bool sortedAscending() const; MediaPlayListProxyModel* playList() const; public Q_SLOTS: void setFilterText(const QString &filterText); void setFilterRating(int filterRating); void sortModel(Qt::SortOrder order); void setPlayList(MediaPlayListProxyModel* playList); + void enqueueToPlayList(); + + void replaceAndPlayOfPlayList(); + Q_SIGNALS: void filterTextChanged(const QString &filterText); void filterRatingChanged(int filterRating); void sortedAscendingChanged(); void playListChanged(); void entriesToEnqueue(const DataTypes::EntryDataList &newEntries, ElisaUtils::PlayListEnqueueMode enqueueMode, ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay); protected: bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override = 0; void disconnectPlayList(); void connectPlayList(); QString mFilterText; int mFilterRating = 0; QRegularExpression mFilterExpression; QReadWriteLock mDataLock; QThreadPool mThreadPool; MediaPlayListProxyModel* mPlayList = nullptr; +private: + + void genericEnqueueToPlayList(ElisaUtils::PlayListEnqueueMode enqueueMode, + ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay); + }; #endif // ABSTRACTMEDIAPROXYMODEL_H diff --git a/src/models/alltracksproxymodel.cpp b/src/models/alltracksproxymodel.cpp index 6b75f4c8..b0bf0aee 100644 --- a/src/models/alltracksproxymodel.cpp +++ b/src/models/alltracksproxymodel.cpp @@ -1,74 +1,44 @@ /* SPDX-FileCopyrightText: 2017 (c) Alexander Stippich SPDX-License-Identifier: LGPL-3.0-or-later */ #include "alltracksproxymodel.h" #include "datatypes.h" -#include -#include - AllTracksProxyModel::AllTracksProxyModel(QObject *parent) : AbstractMediaProxyModel(parent) { setSortCaseSensitivity(Qt::CaseInsensitive); } AllTracksProxyModel::~AllTracksProxyModel() = default; bool AllTracksProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { bool result = false; auto currentIndex = sourceModel()->index(source_row, 0, source_parent); const auto &titleValue = sourceModel()->data(currentIndex, Qt::DisplayRole).toString(); const auto &artistValue = sourceModel()->data(currentIndex, DataTypes::ColumnsRoles::ArtistRole).toString(); const auto maximumRatingValue = sourceModel()->data(currentIndex, DataTypes::ColumnsRoles::RatingRole).toInt(); if (maximumRatingValue < mFilterRating) { return result; } if (mFilterExpression.match(titleValue).hasMatch()) { result = true; } if (mFilterExpression.match(artistValue).hasMatch()) { result = true; } return result; } -void AllTracksProxyModel::genericEnqueueToPlayList(ElisaUtils::PlayListEnqueueMode enqueueMode, - ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay) -{ - QtConcurrent::run(&mThreadPool, [=] () { - QReadLocker locker(&mDataLock); - auto allTracks = DataTypes::EntryDataList{}; - allTracks.reserve(rowCount()); - for (int rowIndex = 0, maxRowCount = rowCount(); rowIndex < maxRowCount; ++rowIndex) { - auto currentIndex = index(rowIndex, 0); - allTracks.push_back(DataTypes::EntryData{data(currentIndex, DataTypes::FullDataRole).value(), - data(currentIndex, DataTypes::ColumnsRoles::TitleRole).toString(), - data(currentIndex, DataTypes::ColumnsRoles::ResourceRole).toUrl()}); - } - Q_EMIT entriesToEnqueue(allTracks, enqueueMode, triggerPlay); - }); -} - -void AllTracksProxyModel::enqueueToPlayList() -{ - genericEnqueueToPlayList(ElisaUtils::AppendPlayList, ElisaUtils::DoNotTriggerPlay); -} - -void AllTracksProxyModel::replaceAndPlayOfPlayList() -{ - genericEnqueueToPlayList(ElisaUtils::ReplacePlayList, ElisaUtils::TriggerPlay); -} - #include "moc_alltracksproxymodel.cpp" diff --git a/src/models/alltracksproxymodel.h b/src/models/alltracksproxymodel.h index 007f2359..e87752f3 100644 --- a/src/models/alltracksproxymodel.h +++ b/src/models/alltracksproxymodel.h @@ -1,45 +1,38 @@ /* SPDX-FileCopyrightText: 2017 (c) Alexander Stippich SPDX-FileCopyrightText: 2018 (c) Matthieu Gallien SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef ALLTRACKSPROXYMODEL_H #define ALLTRACKSPROXYMODEL_H #include "elisaLib_export.h" #include "abstractmediaproxymodel.h" #include "elisautils.h" class ELISALIB_EXPORT AllTracksProxyModel : public AbstractMediaProxyModel { Q_OBJECT public: explicit AllTracksProxyModel(QObject *parent = nullptr); ~AllTracksProxyModel() override; Q_SIGNALS: public Q_SLOTS: - void enqueueToPlayList(); - - void replaceAndPlayOfPlayList(); - protected: bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; private: - void genericEnqueueToPlayList(ElisaUtils::PlayListEnqueueMode enqueueMode, - ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay); - }; #endif // ALLTRACKSPROXYMODEL_H diff --git a/src/models/gridviewproxymodel.cpp b/src/models/gridviewproxymodel.cpp index 2d5df7eb..d55f9229 100644 --- a/src/models/gridviewproxymodel.cpp +++ b/src/models/gridviewproxymodel.cpp @@ -1,105 +1,62 @@ /* SPDX-FileCopyrightText: 2016 (c) Matthieu Gallien SPDX-FileCopyrightText: 2017 (c) Alexander Stippich SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gridviewproxymodel.h" #include "datatypes.h" #include "elisautils.h" #include #include GridViewProxyModel::GridViewProxyModel(QObject *parent) : AbstractMediaProxyModel(parent) { setSortRole(Qt::DisplayRole); setSortCaseSensitivity(Qt::CaseInsensitive); sortModel(Qt::AscendingOrder); } -ElisaUtils::PlayListEntryType GridViewProxyModel::dataType() const -{ - return mDataType; -} - GridViewProxyModel::~GridViewProxyModel() = default; bool GridViewProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { bool result = false; auto currentIndex = sourceModel()->index(source_row, 0, source_parent); const auto &mainValue = sourceModel()->data(currentIndex, Qt::DisplayRole).toString(); const auto &artistValue = sourceModel()->data(currentIndex, DataTypes::ArtistRole).toString(); const auto &allArtistsValue = sourceModel()->data(currentIndex, DataTypes::AllArtistsRole).toStringList(); const auto maximumRatingValue = sourceModel()->data(currentIndex, DataTypes::HighestTrackRating).toInt(); if (maximumRatingValue < mFilterRating) { result = false; return result; } if (mFilterExpression.match(mainValue).hasMatch()) { result = true; return result; } if (mFilterExpression.match(artistValue).hasMatch()) { result = true; return result; } for (const auto &oneArtist : allArtistsValue) { if (mFilterExpression.match(oneArtist).hasMatch()) { result = true; return result; } } return result; } -void GridViewProxyModel::genericEnqueueToPlayList(ElisaUtils::PlayListEnqueueMode enqueueMode, - ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay) -{ - QtConcurrent::run(&mThreadPool, [=] () { - QReadLocker locker(&mDataLock); - auto allData = DataTypes::EntryDataList{}; - allData.reserve(rowCount()); - for (int rowIndex = 0, maxRowCount = rowCount(); rowIndex < maxRowCount; ++rowIndex) { - auto currentIndex = index(rowIndex, 0); - - allData.push_back(DataTypes::EntryData{data(currentIndex, DataTypes::FullDataRole).value(), - data(currentIndex, Qt::DisplayRole).toString(), {}}); - } - Q_EMIT entriesToEnqueue(allData, enqueueMode, triggerPlay); - }); -} - -void GridViewProxyModel::enqueueToPlayList() -{ - genericEnqueueToPlayList(ElisaUtils::AppendPlayList, ElisaUtils::DoNotTriggerPlay); -} - -void GridViewProxyModel::replaceAndPlayOfPlayList() -{ - genericEnqueueToPlayList(ElisaUtils::ReplacePlayList, ElisaUtils::TriggerPlay); -} - -void GridViewProxyModel::setDataType(ElisaUtils::PlayListEntryType newDataType) -{ - if (mDataType == newDataType) { - return; - } - - mDataType = newDataType; - - Q_EMIT dataTypeChanged(); -} - #include "moc_gridviewproxymodel.cpp" diff --git a/src/models/gridviewproxymodel.h b/src/models/gridviewproxymodel.h index 550b6667..b6950623 100644 --- a/src/models/gridviewproxymodel.h +++ b/src/models/gridviewproxymodel.h @@ -1,56 +1,36 @@ /* SPDX-FileCopyrightText: 2016 (c) Matthieu Gallien SPDX-FileCopyrightText: 2017 (c) Alexander Stippich SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef GRIDVIEWPROXYMODEL_H #define GRIDVIEWPROXYMODEL_H #include "elisaLib_export.h" #include "abstractmediaproxymodel.h" -#include "elisautils.h" class ELISALIB_EXPORT GridViewProxyModel : public AbstractMediaProxyModel { Q_OBJECT - Q_PROPERTY(ElisaUtils::PlayListEntryType dataType READ dataType WRITE setDataType NOTIFY dataTypeChanged) - public: explicit GridViewProxyModel(QObject *parent = nullptr); ~GridViewProxyModel() override; - ElisaUtils::PlayListEntryType dataType() const; - Q_SIGNALS: - void dataTypeChanged(); - public Q_SLOTS: - void enqueueToPlayList(); - - void replaceAndPlayOfPlayList(); - - void setDataType(ElisaUtils::PlayListEntryType newDataType); - protected: bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; -private: - - void genericEnqueueToPlayList(ElisaUtils::PlayListEnqueueMode enqueueMode, - ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay); - - ElisaUtils::PlayListEntryType mDataType = ElisaUtils::Unknown; - }; #endif // GRIDVIEWPROXYMODEL_H diff --git a/src/qml/DataGridView.qml b/src/qml/DataGridView.qml index 37b8b096..5454c127 100644 --- a/src/qml/DataGridView.qml +++ b/src/qml/DataGridView.qml @@ -1,97 +1,96 @@ /* SPDX-FileCopyrightText: 2018 (c) Matthieu Gallien SPDX-License-Identifier: LGPL-3.0-or-later */ import QtQuick 2.10 import QtQuick.Controls 2.3 import org.kde.kirigami 2.5 as Kirigami import org.kde.elisa 1.0 FocusScope { id: viewHeader property var filterType property alias mainTitle: gridView.mainTitle property alias secondaryTitle: gridView.secondaryTitle property alias image: gridView.image property var modelType property alias defaultIcon: gridView.defaultIcon property alias showRating: gridView.showRating property alias delegateDisplaySecondaryText: gridView.delegateDisplaySecondaryText property alias isSubPage: gridView.isSubPage property alias expandedFilterView: gridView.expandedFilterView property string genreFilterText property string artistFilter focus: true Accessible.role: Accessible.Pane Accessible.name: mainTitle function initializeModel() { realModel.initialize(elisa.musicManager, elisa.musicManager.viewDatabase, modelType, filterType, genreFilterText, artistFilter, 0) } DataModel { id: realModel } GridViewProxyModel { id: proxyModel sourceModel: realModel - dataType: modelType playList: elisa.mediaPlayListProxyModel } GridBrowserView { id: gridView focus: true anchors.fill: parent contentModel: proxyModel onEnqueue: elisa.mediaPlayListProxyModel.enqueue(databaseId, name, modelType, ElisaUtils.AppendPlayList, ElisaUtils.DoNotTriggerPlay) onReplaceAndPlay: elisa.mediaPlayListProxyModel.enqueue(databaseId, name, modelType, ElisaUtils.ReplacePlayList, ElisaUtils.TriggerPlay) onOpen: viewManager.openChildView(innerMainTitle, innerSecondaryTitle, innerImage, databaseId, dataType) onGoBack: viewManager.goBack() Loader { anchors.centerIn: parent height: Kirigami.Units.gridUnit * 5 width: height visible: realModel.isBusy active: realModel.isBusy sourceComponent: BusyIndicator { anchors.centerIn: parent } } } Connections { target: elisa onMusicManagerChanged: initializeModel() } Component.onCompleted: { if (elisa.musicManager) { initializeModel() } } }