diff --git a/TODO.org b/TODO.org index e1c2689..3fcebfe 100644 --- a/TODO.org +++ b/TODO.org @@ -1,9 +1,9 @@ #+TITLE: Todo List * Inbox -** TODO Need to make ListModel capable of bringing in a string list +** TODO Need to make ListModel capable of bringing in a string list [1/2] [50%] +- [X] Create a Model +- [ ] Create a class that we'll make a list of in the model -[[file:~/dev/church-presenter/src/qml/presenter/LeftDock.qml::/* showPassiveNotification(serviceItemList.currentIndex); */]] -** TODO Parse Lyrics to create a list of strings for slides +** DONE Parse Lyrics to create a list of strings for slides SCHEDULED: <2022-03-23 Wed 10:00> -[[file:~/dev/church-presenter/src/qml/presenter/LeftDock.qml::/* showPassiveNotification(serviceItemList.currentIndex); */]] diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6d72383..fe6f05d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,6 +4,7 @@ target_sources(presenter PRIVATE main.cpp resources.qrc songsqlmodel.cpp songsqlmodel.h + serviceitemmodel.cpp serviceitemmodel.h serviceitem.cpp serviceitem.h videosqlmodel.cpp videosqlmodel.h mpv/mpvobject.h mpv/mpvobject.cpp diff --git a/src/main.cpp b/src/main.cpp index ed2f64c..4641cbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,6 +31,7 @@ #include #include "mpv/mpvobject.h" +#include "serviceitemmodel.h" #include "songsqlmodel.h" #include "videosqlmodel.h" @@ -89,6 +90,7 @@ int main(int argc, char *argv[]) //register our models qmlRegisterType("org.presenter", 1, 0, "SongSqlModel"); qmlRegisterType("org.presenter", 1, 0, "VideoSqlModel"); + qmlRegisterType("org.presenter", 1, 0, "ServiceItemModel"); connectToDatabase(); diff --git a/src/qml/presenter/LeftDock.qml b/src/qml/presenter/LeftDock.qml index a5508d9..7b06297 100644 --- a/src/qml/presenter/LeftDock.qml +++ b/src/qml/presenter/LeftDock.qml @@ -36,9 +36,9 @@ ColumnLayout { onDropped: { appendItem(dragItemTitle, dragItemType, - dragItemText, - dragItemBackgroundType, dragItemBackground, + dragItemBackgroundType, + dragItemText, dragItemIndex); } keys: ["library"] @@ -46,7 +46,7 @@ ColumnLayout { ListView { id: serviceItemList anchors.fill: parent - model: serviceListModel + model: serviceItemModel delegate: Kirigami.DelegateRecycler { width: serviceItemList.width sourceComponent: itemDelegate @@ -108,7 +108,7 @@ ColumnLayout { anchors.fill: parent listItem: serviceItem listView: serviceItemList - onMoveRequested: serviceListModel.move(oldIndex, newIndex, 1) + onMoveRequested: serviceItemModel.move(oldIndex, newIndex) onClicked: { serviceItemList.currentIndex = index; /* showPassiveNotification(serviceItemList.currentIndex); */ @@ -147,56 +147,27 @@ ColumnLayout { anchors.rightMargin: 0 active: hovered || pressed } - - ListModel { - id: serviceListModel - ListElement { - name: "10,000 Reason" - type: "song" - text: "YIP YIP!" - backgroundType: "image" - background: "file:/home/chris/nextcloud/tfc/openlp/CMG - Nature King 21.jpg" - } - ListElement { - name: "Marvelous Light" - type: "song" - text: "HALLELUJAH!" - backgroundType: "video" - background: "file:/home/chris/nextcloud/tfc/openlp/Fire Embers_Loop.mp4" - } - ListElement { - name: "Test" - type: "video" - text: "" - backgroundType: "video" - background: "file:/home/chris/nextcloud/tfc/openlp/videos/test.mp4" - } - } } } - function addItem(index, name, type, text, backgroundType, background, itemID) { - serviceListModel.insert(index, { - "name": name, - "type": type, - "text": text, - "backgroundType": backgroundType, - "background": background}) + function addItem(index, name, type, + background, backgroundType, text, itemID) { + serviceItemModel.insertItem(index, name, + type, text, background, + backgroundType) } - function appendItem(name, type, text, backgroundType, background, itemID) { - serviceListModel.append({ - "name": name, - "type": type, - "text": text, - "backgroundType": backgroundType, - "background": background}); - + function appendItem(name, type, background, backgroundType, text, itemID) { + let lyrics; if (type == "song") { - const lyrics = songsqlmodel.getLyricList(itemID); - /* print(lyrics); */ + lyrics = songsqlmodel.getLyricList(itemID); + print(lyrics); } + print(background); + print(backgroundType); + + serviceItemModel.addItem(name, type, background, + backgroundType, lyrics); } } - diff --git a/src/qml/presenter/MainWindow.qml b/src/qml/presenter/MainWindow.qml index ee95f78..938718d 100644 --- a/src/qml/presenter/MainWindow.qml +++ b/src/qml/presenter/MainWindow.qml @@ -129,6 +129,10 @@ Controls.Page { id: videosqlmodel } + ServiceItemModel { + id: serviceItemModel + } + function changeSlideType(type) { presentation.itemType = type; if (slideItem) diff --git a/src/serviceitem.cpp b/src/serviceitem.cpp index e465381..118e503 100644 --- a/src/serviceitem.cpp +++ b/src/serviceitem.cpp @@ -1,88 +1,96 @@ #include "serviceitem.h" -#include ServiceItem::ServiceItem(QObject *parent) - : QAbstractListModel(parent) + : QObject{parent} { + } -int ServiceItem::rowCount(const QModelIndex &parent) const +ServiceItem::ServiceItem(const QString &name, const QString &type, QObject *parent) + : QObject(parent),m_name(name),m_type(type) { - // For list models only the root node (an invalid parent) should return the list's size. For all - // other (valid) parents, rowCount() should return 0 so that it does not become a tree model. - if (parent.isValid()) - return 0; - // FIXME: Implement me! - return m_data.count(); } -QVariant ServiceItem::data(const QModelIndex &index, int role) const +ServiceItem::ServiceItem(const QString &name, const QString &type, const QString &background, + const QString &backgroundType, QObject *parent) + : QObject(parent),m_name(name),m_type(type),m_background(background),m_backgroundType(backgroundType) { - if (!index.isValid()) - return QVariant(); - const Data &data = m_data.at(index.row()); - switch (role) { - case NameRole: - return data.name; - case TypeRole: - return data.type; - case BackgroundRole: - return data.background; - case BackgroundTypeRole: - return data.backgroundType; - case TextRole: - return data.text; - default: - return QVariant(); - } } -QHash ServiceItem::roleNames() const { - static QHash mapping { - {NameRole, "name"}, - {TypeRole, "type"}, - {BackgroundRole, "background"}, - {BackgroundTypeRole, "backgroundType"}, - {TextRole, "text"} - }; - - return mapping; -} - -bool ServiceItem::setData(const QModelIndex &index, - const QVariant &value, - int role) { - const Data &oldData = m_data.at(index.row()); - const QVariant newData = data(index, role); - if (newData != value) { - // FIXME: Implement me! - switch (role) { - case NameRole: - m_data.at(index.row()).name = newData.toString(); - case TypeRole: - return data.type; - case BackgroundRole: - return data.background; - case BackgroundTypeRole: - return data.backgroundType; - case TextRole: - return data.text; - default: - return QVariant(); - } - oldData = newData; - emit dataChanged(index, index, QVector() << role); - return true; - } - return false; -} - -Qt::ItemFlags ServiceItem::flags(const QModelIndex &index) const +ServiceItem::ServiceItem(const QString &name, const QString &type, const QString &background, + const QString &backgroundType, const QStringList &text, QObject *parent) + : QObject(parent),m_name(name),m_type(type),m_background(background),m_backgroundType(backgroundType),m_text(text) { - if (!index.isValid()) - return Qt::NoItemFlags; - return Qt::ItemIsEditable; // FIXME: Implement me! +} + +QString ServiceItem::name() const { + return m_name; +} + +QString ServiceItem::type() const { + return m_type; +} + +QString ServiceItem::background() const +{ + return m_background; +} + +QString ServiceItem::backgroundType() const +{ + return m_backgroundType; +} + +QStringList ServiceItem::text() const +{ + return m_text; +} + +void ServiceItem::setName(QString name) +{ + if (m_name == name) + return; + + m_name = name; + emit nameChanged(m_name); +} + +void ServiceItem::setType(QString type) +{ + if (m_type == type) + return; + + m_type = type; + emit typeChanged(m_type); +} + +void ServiceItem::setBackground(QString background) +{ + if (m_background == background) + return; + + m_background = background; + emit backgroundChanged(m_background); +} + +void ServiceItem::setBackgroundType(QString backgroundType) +{ + if (m_backgroundType == backgroundType) + return; + + m_backgroundType = backgroundType; + emit backgroundTypeChanged(m_backgroundType); +} + +void ServiceItem::setText(QStringList text) +{ + if (m_text == text) + return; + + m_text = text; + emit textChanged(m_text); + } diff --git a/src/serviceitem.h b/src/serviceitem.h index cc893cc..95d06c6 100644 --- a/src/serviceitem.h +++ b/src/serviceitem.h @@ -1,54 +1,51 @@ #ifndef SERVICEITEM_H #define SERVICEITEM_H -#include -#include +#include +#include -struct Data { - Data() {} - Data( const QString& name, - const QString& type, - const QString& background, - const QString& backgroundType, - const QStringList& text) - : name(name), type(type), background(background), - backgroundType(backgroundType), text(text) {} - QString name; - QString type; - QString background; - QString backgroundType; - QStringList text; -}; - -class ServiceItem : public QAbstractListModel +class ServiceItem : public QObject { Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(QString type READ type WRITE setType NOTIFY typeChanged) + Q_PROPERTY(QString background READ background WRITE setBackground NOTIFY backgroundChanged) + Q_PROPERTY(QString backgroundType READ backgroundType WRITE setBackgroundType NOTIFY backgroundTypeChanged) + Q_PROPERTY(QStringList text READ text WRITE setText NOTIFY textChanged) public: explicit ServiceItem(QObject *parent = nullptr); + ServiceItem(const QString &name, const QString &type, QObject * parent = nullptr); + ServiceItem(const QString &name, const QString &type, const QString &background, + const QString &backgroundType, QObject * parent = nullptr); + ServiceItem(const QString &name, const QString &type, const QString &background, + const QString &backgroundType, const QStringList &text, QObject * parent = nullptr); - enum Roles { - NameRole = Qt::UserRole, - TypeRole, - BackgroundRole, - BackgroundTypeRole, - TextRole, - SlidesRole - }; + QString name() const; + QString type() const; + QString background() const; + QString backgroundType() const; + QStringList text() const; - // Basic functionality: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - QHash roleNames() const override; + void setName(QString name); + void setType(QString type); + void setBackground(QString background); + void setBackgroundType(QString backgroundType); + void setText(QStringList text); - // Editable: - bool setData(const QModelIndex &index, const QVariant &value, - int role = Qt::EditRole) override; - - Qt::ItemFlags flags(const QModelIndex& index) const override; +signals: + void nameChanged(QString name); + void typeChanged(QString type); + void backgroundChanged(QString background); + void backgroundTypeChanged(QString backgroundType); + void textChanged(QStringList text); private: - QVector m_data; + QString m_name; + QString m_type; + QString m_background; + QString m_backgroundType; + QStringList m_text; }; #endif // SERVICEITEM_H diff --git a/src/serviceitemmodel.cpp b/src/serviceitemmodel.cpp new file mode 100644 index 0000000..3d1d196 --- /dev/null +++ b/src/serviceitemmodel.cpp @@ -0,0 +1,190 @@ +#include "serviceitemmodel.h" +#include "serviceitem.h" +#include +#include +#include +#include + +ServiceItemModel::ServiceItemModel(QObject *parent) + : QAbstractListModel(parent) { + addItem(new ServiceItem("10,000 Resons", "song", + "file:/home/chris/nextcloud/tfc/openlp/CMG - Nature King 21.jpg", + "image", QStringList("Yip Yip"))); + addItem(new ServiceItem("Marvelous Light", "song", + "file:/home/chris/nextcloud/tfc/openlp/Fire Embers_Loop.mp4", + "video", QStringList("Hallelujah!"))); + addItem(new ServiceItem("BP Text", "video", + "file:/home/chris/nextcloud/tfc/openlp/videos/test.mp4", + "video", QStringList())); +} + +int ServiceItemModel::rowCount(const QModelIndex &parent) const { + // For list models only the root node (an invalid parent) should return the + // list's size. For all other (valid) parents, rowCount() should return 0 so + // that it does not become a tree model. + if (parent.isValid()) + return 0; + + // FIXME: Implement me! + return m_items.size(); +} + +QVariant ServiceItemModel::data(const QModelIndex &index, int role) const { + if (!index.isValid()) + return QVariant(); + + ServiceItem *item = m_items[index.row()]; + switch (role) { + case NameRole: + return item->name(); + case TypeRole: + return item->type(); + case BackgroundRole: + return item->background(); + case BackgroundTypeRole: + return item->backgroundType(); + case TextRole: + return item->text(); + default: + return QVariant(); + } +} + +QHash ServiceItemModel::roleNames() const { + static QHash mapping{{NameRole, "name"}, + {TypeRole, "type"}, + {BackgroundRole, "background"}, + {BackgroundTypeRole, "backgroundType"}, + {TextRole, "text"}}; + + return mapping; +} + +bool ServiceItemModel::setData(const QModelIndex &index, const QVariant &value, + int role) { + + ServiceItem *item = m_items[index.row()]; + bool somethingChanged = false; + + switch (role) { + case NameRole: + if (item->name() != value.toString()) { + item->setName(value.toString()); + somethingChanged = true; + } + break; + case TypeRole: + if (item->type() != value.toString()) { + item->setType(value.toString()); + somethingChanged = true; + } + break; + case BackgroundRole: + if (item->background() != value.toString()) { + item->setBackground(value.toString()); + somethingChanged = true; + } + break; + case BackgroundTypeRole: + if (item->backgroundType() != value.toString()) { + item->setBackgroundType(value.toString()); + somethingChanged = true; + } + break; + case TextRole: + if (item->text() != value.toStringList()) { + item->setText(value.toStringList()); + somethingChanged = true; + } + break; + if (somethingChanged) { + emit dataChanged(index, index, QVector() << role); + return true; + } + } + + return false; +} + +Qt::ItemFlags ServiceItemModel::flags(const QModelIndex &index) const { + if (!index.isValid()) + return Qt::NoItemFlags; + + return Qt::ItemIsEditable; // FIXME: Implement me! +} + +void ServiceItemModel::addItem(ServiceItem *item) { + const int index = m_items.size(); + beginInsertRows(QModelIndex(), index, index); + m_items.append(item); + endInsertRows(); +} + +void ServiceItemModel::insertItem(const int &index, ServiceItem *item) { + beginInsertRows(this->index(index), index, index); + m_items.insert(index, item); + endInsertRows(); + qDebug() << "Success"; +} + +void ServiceItemModel::addItem(const QString &name, const QString &type) { + ServiceItem *item = new ServiceItem(name, type); + addItem(item); +} + +void ServiceItemModel::addItem(const QString &name, const QString &type, + const QString &background, const QString &backgroundType) { + ServiceItem *item = new ServiceItem(name, type, background, backgroundType); + addItem(item); +} + +void ServiceItemModel::addItem(const QString &name, const QString &type, + const QString &background, const QString &backgroundType, + const QStringList &text) { + ServiceItem *item = new ServiceItem(name, type, background, backgroundType, text); + addItem(item); + qDebug() << name << type << background; +} + +void ServiceItemModel::insertItem(const int &index, const QString &name, const QString &type) { + ServiceItem *item = new ServiceItem(name, type); + insertItem(index, item); + qDebug() << name << type; +} + +void ServiceItemModel::insertItem(const int &index, const QString &name, const QString &type, + const QString &background, const QString &backgroundType) { + ServiceItem *item = new ServiceItem(name, type, background, backgroundType); + insertItem(index, item); + qDebug() << name << type << background; +} + +void ServiceItemModel::insertItem(const int &index, const QString &name, const QString &type, + const QString &background, const QString &backgroundType, + const QStringList &text) { + ServiceItem *item = new ServiceItem(name, type, background, backgroundType, text); + insertItem(index, item); + qDebug() << name << type << background; +} + +void ServiceItemModel::removeItem(int index) { + beginRemoveRows(QModelIndex(), index, index); + m_items.removeAt(index); + endRemoveRows(); +} + +bool ServiceItemModel::move(int sourceIndex, int destIndex) { + qDebug() << "starting move"; + QModelIndex parent = index(sourceIndex).parent(); + bool begsuc = beginMoveRows(parent, sourceIndex, sourceIndex, parent, destIndex); + qDebug() << begsuc; + if (!begsuc) { + qDebug() << "Failed to start moving rows"; + m_items.move(sourceIndex, destIndex); + return false; + } + // bool success = moveRow(index(sourceIndex).parent(), sourceIndex, index(destIndex).parent(), destIndex); + endMoveRows(); + // qDebug() << success; + return true; +} diff --git a/src/serviceitemmodel.h b/src/serviceitemmodel.h new file mode 100644 index 0000000..7ec670d --- /dev/null +++ b/src/serviceitemmodel.h @@ -0,0 +1,64 @@ +#ifndef SERVICEITEMMODEL_H +#define SERVICEITEMMODEL_H + +#include "serviceitem.h" +#include +#include +#include +#include +#include + +class ServiceItemModel : public QAbstractListModel { + Q_OBJECT + +public: + explicit ServiceItemModel(QObject *parent = nullptr); + + enum Roles { + NameRole = Qt::UserRole, + TypeRole, + BackgroundRole, + BackgroundTypeRole, + TextRole + }; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, + int role = Qt::DisplayRole) const override; + QHash roleNames() const override; + + // Editable: + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole) override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + + // Helper methods + void addItem(ServiceItem *item); + void insertItem(const int &index, ServiceItem *item); + Q_INVOKABLE void addItem(const QString &name, const QString &type); + // Q_INVOKABLE void addItem(const QString &name, const QString &type, + // const QString &background); + Q_INVOKABLE void addItem(const QString &name, const QString &type, + const QString &background, + const QString &backgroundType); + Q_INVOKABLE void addItem(const QString &name, const QString &type, + const QString &background, + const QString &backgroundType, + const QStringList &text); + Q_INVOKABLE void insertItem(const int &index, const QString &name, + const QString &type); + Q_INVOKABLE void insertItem(const int &index, const QString &name, + const QString &type, const QString &background, + const QString &backgroundType); + Q_INVOKABLE void insertItem(const int &index, const QString &name, + const QString &type, const QString &background, + const QString &backgroundType, const QStringList &text); + Q_INVOKABLE void removeItem(int index); + Q_INVOKABLE bool move(int sourceIndex, int destIndex); + +private: + QList m_items; +}; + +#endif // SERVICEITEMMODEL_H