From a9286eeb1bec6aa835365abbc50ea621a64de9e2 Mon Sep 17 00:00:00 2001 From: Chris Cochrun Date: Thu, 22 Sep 2022 05:59:38 -0500 Subject: [PATCH] adding a presentation model and including it's ui in library --- src/main.cpp | 2 + src/pressqlmodel.cpp | 184 +++++++++++++++++++++++++++++++ src/pressqlmodel.h | 49 ++++++++ src/qml/presenter/Library.qml | 121 ++++++++++++++++++++ src/qml/presenter/MainWindow.qml | 4 + 5 files changed, 360 insertions(+) create mode 100644 src/pressqlmodel.cpp create mode 100644 src/pressqlmodel.h diff --git a/src/main.cpp b/src/main.cpp index 87bc7b0..429295c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,6 +38,7 @@ #include "songsqlmodel.h" #include "videosqlmodel.h" #include "imagesqlmodel.h" +#include "pressqlmodel.h" #include "slide.h" static void connectToDatabase() { @@ -105,6 +106,7 @@ int main(int argc, char *argv[]) qmlRegisterType("org.presenter", 1, 0, "SongSqlModel"); qmlRegisterType("org.presenter", 1, 0, "VideoSqlModel"); qmlRegisterType("org.presenter", 1, 0, "ImageSqlModel"); + qmlRegisterType("org.presenter", 1, 0, "PresSqlModel"); qmlRegisterType("org.presenter", 1, 0, "ServiceItemModel"); qmlRegisterSingletonInstance("org.presenter", 1, 0, "SlideObject", slide.get()); diff --git a/src/pressqlmodel.cpp b/src/pressqlmodel.cpp new file mode 100644 index 0000000..d6b86f9 --- /dev/null +++ b/src/pressqlmodel.cpp @@ -0,0 +1,184 @@ +#include "pressqlmodel.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char *presTableName = "presentation"; + +static void createPresTable() +{ + if(QSqlDatabase::database().tables().contains(presTableName)) { + return; + } + + QSqlQuery query; + if (!query.exec("CREATE TABLE IF NOT EXISTS 'presentations' (" + " 'id' INTEGER NOT NULL," + " 'title' TEXT NOT NULL," + " 'filePath' TEXT NOT NULL," + " PRIMARY KEY(id))")) { + qFatal("Failed to query database: %s", + qPrintable(query.lastError().text())); + } + qDebug() << query.lastQuery(); + qDebug() << "inserting into presentations"; + + query.exec("INSERT INTO presentations (title, filePath) VALUES ('Dec 180', 'file:///home/chris/nextcloud/tfc/openlp/5 slides-2.pdf')"); + qDebug() << query.lastQuery(); + query.exec("INSERT INTO presentations (title, filePath) VALUES ('No TFC', " + "'file:///home/chris/nextcloud/tfc/openlp/5 slides-1.pdf')"); + + query.exec("select * from presentations"); + qDebug() << query.lastQuery(); +} + +PresSqlModel::PresSqlModel(QObject *parent) : QSqlTableModel(parent) { + qDebug() << "creating pres table"; + createPresTable(); + setTable(pressTableName); + setEditStrategy(QSqlTableModel::OnManualSubmit); + // make sure to call select else the model won't fill + select(); +} + +QVariant PresSqlModel::data(const QModelIndex &index, int role) const { + if (role < Qt::UserRole) { + return QSqlTableModel::data(index, role); + } + + // qDebug() << role; + const QSqlRecord sqlRecord = record(index.row()); + return sqlRecord.value(role - Qt::UserRole); +} + +QHash PresSqlModel::roleNames() const +{ + QHash names; + names[Qt::UserRole] = "id"; + names[Qt::UserRole + 1] = "title"; + names[Qt::UserRole + 2] = "filePath"; + return names; +} + +void PresSqlModel::newPres(const QUrl &filePath) { + qDebug() << "adding new pres"; + int rows = rowCount(); + + qDebug() << rows; + QSqlRecord recordData = record(); + QFileInfo fileInfo = filePath.toString(); + QString title = fileInfo.baseName(); + recordData.setValue("title", title); + recordData.setValue("filePath", filePath); + + if (insertRecord(rows, recordData)) { + submitAll(); + } else { + qDebug() << lastError(); + }; +} + +void PresSqlModel::deletePres(const int &row) { + QSqlRecord recordData = record(row); + if (recordData.isEmpty()) + return; + + removeRow(row); + submitAll(); +} + +int PresSqlModel::id() const { + return m_id; +} + +QString PresSqlModel::title() const { + return m_title; +} + +void PresSqlModel::setTitle(const QString &title) { + if (title == m_title) + return; + + m_title = title; + + select(); + emit titleChanged(); +} + +// This function is for updating the title from outside the delegate +void PresSqlModel::updateTitle(const int &row, const QString &title) { + qDebug() << "Row is " << row; + QSqlRecord rowdata = record(row); + qDebug() << rowdata; + rowdata.setValue("title", title); + setRecord(row, rowdata); + qDebug() << rowdata; + submitAll(); + emit titleChanged(); +} + +QUrl PresSqlModel::filePath() const { + return m_filePath; +} + +void PresSqlModel::setFilePath(const QUrl &filePath) { + if (filePath == m_filePath) + return; + + m_filePath = filePath; + + select(); + emit filePathChanged(); +} + +// This function is for updating the filepath from outside the delegate +void PresSqlModel::updateFilePath(const int &row, const QUrl &filePath) { + qDebug() << "Row is " << row; + QSqlRecord rowdata = record(row); + qDebug() << rowdata; + rowdata.setValue("filePath", filePath); + setRecord(row, rowdata); + qDebug() << rowdata; + submitAll(); + emit filePathChanged(); +} + +QVariantMap PresSqlModel::getPres(const int &row) { + // qDebug() << "Row we are getting is " << row; + // QUrl pres; + // QSqlRecord rec = record(row); + // qDebug() << rec.value("filePath").toUrl(); + // // pres.append(rec.value("title")); + // // pres.append(rec.value("filePath")); + // pres = rec.value("filePath").toUrl(); + // return pres; + + QVariantMap data; + const QModelIndex idx = this->index(row,0); + // qDebug() << idx; + if( !idx.isValid() ) + return data; + const QHash rn = roleNames(); + // qDebug() << rn; + QHashIterator it(rn); + while (it.hasNext()) { + it.next(); + qDebug() << it.key() << ":" << it.value(); + data[it.value()] = idx.data(it.key()); + } + return data; +} diff --git a/src/pressqlmodel.h b/src/pressqlmodel.h new file mode 100644 index 0000000..1d73408 --- /dev/null +++ b/src/pressqlmodel.h @@ -0,0 +1,49 @@ +#ifndef PRESSQLMODEL_H +#define PRESSQLMODEL_H + +#include +#include +#include +#include +#include +#include + +class PresSqlModel : public QSqlTableModel +{ + Q_OBJECT + Q_PROPERTY(int id READ id) + Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged) + Q_PROPERTY(QUrl filePath READ filePath WRITE setFilePath NOTIFY filePathChanged) + QML_ELEMENT + +public: + PresSqlModel(QObject *parent = 0); + + int id() const; + QString title() const; + QUrl filePath() const; + + void setTitle(const QString &title); + void setFilePath(const QUrl &filePath); + + Q_INVOKABLE void updateTitle(const int &row, const QString &title); + Q_INVOKABLE void updateFilePath(const int &row, const QUrl &filePath); + + Q_INVOKABLE void newPres(const QUrl &filePath); + Q_INVOKABLE void deletePres(const int &row); + Q_INVOKABLE QVariantMap getPres(const int &row); + + QVariant data(const QModelIndex &index, int role) const override; + QHash roleNames() const override; + +signals: + void titleChanged(); + void filePathChanged(); + +private: + int m_id; + QString m_title; + QUrl m_filePath; +}; + +#endif //PRESSQLMODEL_H diff --git a/src/qml/presenter/Library.qml b/src/qml/presenter/Library.qml index e08103a..c1f0ac0 100644 --- a/src/qml/presenter/Library.qml +++ b/src/qml/presenter/Library.qml @@ -14,6 +14,7 @@ Item { property bool overlay: false property var videoexts: ["mp4", "webm", "mkv", "avi", "MP4", "WEBM", "MKV"] property var imgexts: ["jpg", "png", "gif", "jpeg", "JPG", "PNG"] + property var presexts: ["pdf", "PDF", "odp", "pptx"] Kirigami.Theme.colorSet: Kirigami.Theme.View @@ -713,6 +714,9 @@ Item { Layout.fillWidth: true Layout.alignment: Qt.AlignTop state: "deselected" + clip: true + model: pressqlmodel + delegate: presDelegate states: [ State { @@ -738,6 +742,118 @@ Item { duration: 300 } } + + Component { + id: presDelegate + Item{ + implicitWidth: ListView.view.width + height: selectedLibrary == "press" ? 50 : 0 + Kirigami.BasicListItem { + id: presListItem + + property bool rightMenu: false + + implicitWidth: presentationLibraryList.width + height: selectedLibrary == "press" ? 50 : 0 + clip: true + label: title + /* subtitle: author */ + supportsMouseEvents: false + backgroundColor: { + if (parent.ListView.isCurrentItem) { + Kirigami.Theme.highlightColor; + } else if (presDragHandler.containsMouse){ + Kirigami.Theme.highlightColor; + } else { + Kirigami.Theme.backgroundColor; + } + } + textColor: { + if (parent.ListView.isCurrentItem || presDragHandler.containsMouse) + activeTextColor; + else + Kirigami.Theme.textColor; + } + + Behavior on height { + NumberAnimation { + easing.type: Easing.OutCubic + duration: 300 + } + } + Drag.active: presDragHandler.drag.active + Drag.hotSpot.x: width / 2 + Drag.hotSpot.y: height / 2 + Drag.keys: [ "library" ] + + states: State { + name: "dragged" + when: presListItem.Drag.active + PropertyChanges { + target: presListItem + x: x + y: y + width: width + height: height + } + ParentChange { + target: presListItem + parent: rootApp.overlay + } + } + + } + + MouseArea { + id: presDragHandler + anchors.fill: parent + hoverEnabled: true + drag { + target: presListItem + onActiveChanged: { + if (presDragHandler.drag.active) { + dragItemTitle = title; + dragItemType = "pres"; + dragItemText = ""; + dragItemBackgroundType = "pres"; + dragItemBackground = filePath; + } else { + presListItem.Drag.drop() + } + } + filterChildren: true + threshold: 10 + } + MouseArea { + id: presClickHandler + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: { + if(mouse.button == Qt.RightButton) + rightClickPresMenu.popup() + else{ + presentationLibraryList.currentIndex = index + const pres = pressqlmodel.getPres(presentationLibraryList.currentIndex); + if (!editMode) + editMode = true; + editType = "pres"; + editSwitch(pres); + } + } + + } + } + Controls.Menu { + id: rightClickPresMenu + x: presClickHandler.mouseX + y: presClickHandler.mouseY + 10 + Kirigami.Action { + text: "delete" + onTriggered: pressqlmodel.deletePres(index) + } + } + } + } } Rectangle { @@ -887,6 +1003,11 @@ Item { { addImg(file); } + if (presexts.includes(extension)) + { + showPassiveNotification("it's a presentation!"); + return; + } } } } diff --git a/src/qml/presenter/MainWindow.qml b/src/qml/presenter/MainWindow.qml index ef36bb7..848d891 100644 --- a/src/qml/presenter/MainWindow.qml +++ b/src/qml/presenter/MainWindow.qml @@ -115,6 +115,10 @@ Controls.Page { id: imagesqlmodel } + PresSqlModel { + id: pressqlmodel + } + ServiceItemModel { id: serviceItemModel }