Implement Filter actions in GUI
This commit is contained in:
parent
531c6a2483
commit
86d1476687
@ -136,6 +136,7 @@ if(ANDROID)
|
||||
list-add
|
||||
list-remove
|
||||
view-refresh
|
||||
view-filter
|
||||
kasts
|
||||
mail-sent
|
||||
globe
|
||||
|
@ -28,9 +28,10 @@ public:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
|
||||
private:
|
||||
public Q_SLOTS:
|
||||
void updateInternalState();
|
||||
|
||||
private:
|
||||
QStringList m_entryIds;
|
||||
QVector<bool> m_read;
|
||||
QVector<bool> m_new;
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include "models/episodeproxymodel.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
EpisodeProxyModel::EpisodeProxyModel()
|
||||
: QSortFilterProxyModel(nullptr)
|
||||
{
|
||||
@ -46,6 +48,37 @@ EpisodeProxyModel::FilterType EpisodeProxyModel::filterType() const
|
||||
|
||||
void EpisodeProxyModel::setFilterType(FilterType type)
|
||||
{
|
||||
m_currentFilter = type;
|
||||
Q_EMIT filterTypeChanged(m_currentFilter);
|
||||
if (type != m_currentFilter) {
|
||||
beginResetModel();
|
||||
// TODO: Connect to signals to capture new and read updates in case those
|
||||
// filters are active. Also disconnect from signals if the filters are
|
||||
// removed
|
||||
m_currentFilter = type;
|
||||
m_episodeModel->updateInternalState();
|
||||
endResetModel();
|
||||
Q_EMIT filterTypeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QString EpisodeProxyModel::filterName() const
|
||||
{
|
||||
return getFilterName(m_currentFilter);
|
||||
}
|
||||
|
||||
QString EpisodeProxyModel::getFilterName(FilterType type) const
|
||||
{
|
||||
switch (type) {
|
||||
case NoFilter:
|
||||
return i18n("No Filter");
|
||||
case ReadFilter:
|
||||
return i18n("Played Episodes");
|
||||
case NotReadFilter:
|
||||
return i18n("Unplayed Episodes");
|
||||
case NewFilter:
|
||||
return i18n("Episodes marked as \"New\"");
|
||||
case NotNewFilter:
|
||||
return i18n("Episodes not marked as \"New\"");
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ public:
|
||||
Q_ENUM(FilterType)
|
||||
|
||||
Q_PROPERTY(FilterType filterType READ filterType WRITE setFilterType NOTIFY filterTypeChanged)
|
||||
Q_PROPERTY(QString filterName READ filterName NOTIFY filterTypeChanged)
|
||||
|
||||
explicit EpisodeProxyModel();
|
||||
~EpisodeProxyModel();
|
||||
@ -32,10 +33,13 @@ public:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
|
||||
FilterType filterType() const;
|
||||
QString filterName() const;
|
||||
void setFilterType(FilterType type);
|
||||
|
||||
Q_INVOKABLE QString getFilterName(FilterType type) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void filterTypeChanged(FilterType filter);
|
||||
void filterTypeChanged();
|
||||
|
||||
private:
|
||||
EpisodeModel *m_episodeModel;
|
||||
|
@ -25,13 +25,84 @@ Kirigami.ScrollablePage {
|
||||
}
|
||||
}
|
||||
|
||||
actions {
|
||||
main: Kirigami.Action {
|
||||
iconName: "view-refresh"
|
||||
text: i18n("Refresh All Podcasts")
|
||||
onTriggered: refreshing = true
|
||||
visible: !Kirigami.Settings.isMobile || episodeList.count === 0
|
||||
actions.main: Kirigami.Action {
|
||||
iconName: "view-filter"
|
||||
text: i18n("Filter")
|
||||
onTriggered: filterTypeOverlay.open();
|
||||
}
|
||||
|
||||
actions.left: Kirigami.Action {
|
||||
iconName: "view-refresh"
|
||||
text: i18n("Refresh All Podcasts")
|
||||
onTriggered: refreshing = true
|
||||
visible: !Kirigami.Settings.isMobile || (episodeList.count === 0 && episodeProxyModel.filterType == EpisodeProxyModel.NoFilter)
|
||||
}
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
id: filterTypeOverlay
|
||||
|
||||
header: Kirigami.Heading {
|
||||
text: i18n("Select Filter")
|
||||
}
|
||||
|
||||
ListView {
|
||||
// TODO: fix automatic width
|
||||
implicitWidth: Kirigami.Units.gridUnit * 12
|
||||
clip: true
|
||||
|
||||
model: ListModel {
|
||||
id: filterModel
|
||||
// have to use script because i18n doesn't work within ListElement
|
||||
Component.onCompleted: {
|
||||
var filterList = [EpisodeProxyModel.NoFilter,
|
||||
EpisodeProxyModel.ReadFilter,
|
||||
EpisodeProxyModel.NotReadFilter,
|
||||
EpisodeProxyModel.NewFilter,
|
||||
EpisodeProxyModel.NotNewFilter]
|
||||
for (var i in filterList) {
|
||||
filterModel.append({"name": episodeProxyModel.getFilterName(filterList[i]),
|
||||
"filterType": filterList[i]});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delegate: Kirigami.BasicListItem {
|
||||
id: swipeDelegate
|
||||
highlighted: filterType === episodeProxyModel.filterType
|
||||
text: name
|
||||
onClicked: {
|
||||
episodeProxyModel.filterType = filterType;
|
||||
filterTypeOverlay.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.InlineMessage {
|
||||
z: 2
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
bottomMargin: (Kirigami.Settings.isMobile ? Kirigami.Units.largeSpacing * 9 : Kirigami.Units.largeSpacing * 2) + (errorNotification.visible ? errorNotification.height : 0)
|
||||
}
|
||||
type: Kirigami.MessageType.Information
|
||||
visible: episodeProxyModel.filterType != EpisodeProxyModel.NoFilter
|
||||
TextMetrics {
|
||||
id: textMetrics
|
||||
text: i18n("Filter Active: ") + episodeProxyModel.filterName
|
||||
}
|
||||
text: textMetrics.text
|
||||
width: Math.min(textMetrics.width + 2 * Kirigami.Units.largeSpacing + 10 * Kirigami.Units.gridUnit, parent.width)
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
id: resetButton
|
||||
icon.name: "edit-delete-remove"
|
||||
text: i18n("Reset")
|
||||
onTriggered: {
|
||||
episodeProxyModel.filterType = EpisodeProxyModel.NoFilter;
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Kirigami.PlaceholderMessage {
|
||||
|
Loading…
x
Reference in New Issue
Block a user