First work on queuemodel

This commit is contained in:
Bart De Vries 2021-03-26 16:26:19 +01:00
parent 8419fe76ec
commit f75c29dda6
5 changed files with 201 additions and 6 deletions

View File

@ -9,6 +9,7 @@ add_executable(alligator
author.cpp
enclosure.cpp
enclosuredownloadjob.cpp
queuemodel.cpp
resources.qrc
)

View File

@ -27,6 +27,7 @@
#include "entriesmodel.h"
#include "feedsmodel.h"
#include "fetcher.h"
#include "queuemodel.h"
#ifdef Q_OS_ANDROID
Q_DECL_EXPORT
@ -45,6 +46,7 @@ int main(int argc, char *argv[])
QCoreApplication::setApplicationName(QStringLiteral("Alligator"));
qmlRegisterType<FeedsModel>("org.kde.alligator", 1, 0, "FeedsModel");
qmlRegisterType<QueueModel>("org.kde.alligator", 1, 0, "QueueModel");
qmlRegisterUncreatableType<EntriesModel>("org.kde.alligator", 1, 0, "EntriesModel", QStringLiteral("Get from Feed"));
qmlRegisterUncreatableType<Enclosure>("org.kde.alligator", 1, 0, "Enclosure", QStringLiteral("Only for enums"));
qmlRegisterSingletonType<Fetcher>("org.kde.alligator", 1, 0, "Fetcher", [](QQmlEngine *engine, QJSEngine *) -> QObject * {

View File

@ -23,13 +23,13 @@ Kirigami.ScrollablePage {
Kirigami.ListItemDragHandle {
listItem: listItem
listView: mainList
onMoveRequested: listModel.move(oldIndex, newIndex, 1)
onMoveRequested: queueModel.moveRows(oldIndex, newIndex, 1)
}
Controls.Label {
Layout.fillWidth: true
height: Math.max(implicitHeight, Kirigami.Units.iconSizes.smallMedium)
text: model.title
text: model.entry.title
color: listItem.checked || (listItem.pressed && !listItem.checked && !listItem.sectionDelegate) ? listItem.activeTextColor : listItem.textColor
}
}
@ -37,8 +37,21 @@ Kirigami.ScrollablePage {
Kirigami.Action {
iconName: "media-playback-start"
text: "Play"
onTriggered: showPassiveNotification(model.title + " Action 1 clicked")
}]
onTriggered: {
audio.entry = model.entry
audio.play()
}
},
Kirigami.Action {
iconName: "delete"
text: i18n("Delete download")
onTriggered: model.entry.enclosure.deleteFile()
visible: model.entry.enclosure && model.entry.enclosure.status === Enclosure.Downloaded
}
]
onClicked: {
pageStack.push("qrc:/EntryPage.qml", {"entry": model.entry})
}
}
}
@ -50,7 +63,7 @@ Kirigami.ScrollablePage {
onTriggered: page.refreshing = false
}
model: ListModel {
/*model: ListModel {
id: listModel
Component.onCompleted: {
for (var i = 0; i < 200; ++i) {
@ -60,7 +73,8 @@ Kirigami.ScrollablePage {
})
}
}
}
}*/
model: QueueModel { id: queueModel }
moveDisplaced: Transition {
YAnimator {

145
src/queuemodel.cpp Normal file
View File

@ -0,0 +1,145 @@
/**
* SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include <QAbstractListModel>
#include <QVariant>
#include <QVector>
#include <QSqlQuery>
#include <QFile>
#include "database.h"
#include "queuemodel.h"
#include "fetcher.h"
QueueModel::QueueModel(QObject *parent)
: QAbstractListModel(parent)
{
connect(&Fetcher::instance(), &Fetcher::downloadFinished, this, [this](const QString &url) {
beginResetModel();
for (auto &entry : m_entries) {
delete entry;
}
m_entries.clear();
updateQueue();
endResetModel();
});
updateQueue();
}
void QueueModel::updateQueue()
{
qDebug() << "Begin create queuemodel object";
QSqlQuery query;
query.prepare(QStringLiteral("SELECT * FROM Enclosures"));
Database::instance().execute(query);
while (query.next()) {
int feed_index = -1;
int entry_index = -1;
QString feedurl = query.value(QStringLiteral("feed")).toString();
QString id = query.value(QStringLiteral("id")).toString();
int duration = query.value(QStringLiteral("duration")).toInt();
int size = query.value(QStringLiteral("size")).toInt();
QString title = query.value(QStringLiteral("title")).toString();
QString type = query.value(QStringLiteral("type")).toString();
QString url = query.value(QStringLiteral("url")).toString();
QFile file(Fetcher::instance().filePath(url));
if(file.size() == size) {
// Enclosure is in database and file has been downloaded !
// Let's find the feed and entry index value so we can create
// an entry object
QSqlQuery feedQuery;
feedQuery.prepare(QStringLiteral("SELECT rowid FROM Feeds WHERE url=:feedurl"));
feedQuery.bindValue(QStringLiteral(":feedurl"), feedurl);
Database::instance().execute(feedQuery);
if (!feedQuery.next()) {
qWarning() << "Feed not found:" << feedurl;
// TODO: remove enclosures belonging to non-existent feed
}
feed_index = feedQuery.value(QStringLiteral("rowid")).toInt() - 1;
qDebug() << feed_index << feedurl;
// Find query index
QSqlQuery entryQuery;
entryQuery.prepare(QStringLiteral("SELECT id FROM Entries WHERE feed=:feedurl;"));
entryQuery.bindValue(QStringLiteral(":feedurl"), feedurl);
entryQuery.bindValue(QStringLiteral(":id"), id);
Database::instance().execute(entryQuery);
int counter = -1;
while (entryQuery.next()) {
counter++;
QString idquery = entryQuery.value(QStringLiteral("id")).toString();
if (idquery == id) entry_index = counter;
}
qDebug() << entry_index << id;
} else {
// TODO: there is some problem with the already downloaded file
// should probably delete the file (and reset status probably not needed)
}
if ((feed_index > -1) && (entry_index > -1)) {
Feed *feed = new Feed(feed_index);
Entry *entry = new Entry(feed, entry_index);
m_entries.append(entry);
}
}
}
QueueModel::~QueueModel()
{
qDeleteAll(m_entries);
}
QVariant QueueModel::data(const QModelIndex &index, int role) const
{
if (role != 0)
return QVariant();
if (m_entries[index.row()] == nullptr)
return QVariant();
return QVariant::fromValue(m_entries[index.row()]);
}
QHash<int, QByteArray> QueueModel::roleNames() const
{
QHash<int, QByteArray> roleNames;
roleNames[0] = "entry";
return roleNames;
}
int QueueModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_entries.size();
}
bool QueueModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild)
{
if (sourceParent != destinationParent) {
return false;
}
if (!beginMoveRows(sourceParent, sourceRow, sourceRow + count - 1, destinationParent, destinationChild)) {
return false;
}
for (auto cptItem = 0; cptItem < count; ++cptItem) {
if (sourceRow < destinationChild) {
m_entries.move(sourceRow, destinationChild - 1);
} else {
m_entries.move(sourceRow, destinationChild);
}
}
endMoveRows();
return true;
}

33
src/queuemodel.h Normal file
View File

@ -0,0 +1,33 @@
/**
* SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#pragma once
#include <QAbstractListModel>
#include <QHash>
#include <QObject>
#include <QString>
#include "entry.h"
class QueueModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit QueueModel(QObject* = nullptr);
~QueueModel() override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex &parent) const override;
bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
private:
void updateQueue();
mutable QList<Entry *> m_entries;
};