diff --git a/src/qml/presenter/ServiceList.qml b/src/qml/presenter/ServiceList.qml
new file mode 100644
index 0000000..31a89a5
--- /dev/null
+++ b/src/qml/presenter/ServiceList.qml
@@ -0,0 +1,438 @@
+import QtQuick 2.13
+/* import QtQuick.Dialogs 1.0 */
+import QtQuick.Controls 2.0 as Controls
+/* import QtQuick.Window 2.13 */
+import QtQuick.Layouts 1.2
+/* import QtQuick.Shapes 1.15 */
+import QtQml.Models 2.12
+/* import QtMultimedia 5.15 */
+/* import QtAudioEngine 1.15 */
+import org.kde.kirigami 2.13 as Kirigami
+import "./" as Presenter
+import org.presenter 1.0
+
+ColumnLayout {
+ id: root
+
+ property var selectedItem: serviceItemList.selected
+ property var hlItem
+
+ Rectangle {
+ id: headerBackground
+ color: Kirigami.Theme.backgroundColor
+ height: 40
+ opacity: 1.0
+ Layout.fillWidth: true
+
+ Kirigami.Heading {
+ id: serviceTitle
+ text: "Service List"
+ anchors.centerIn: headerBackground
+ padding: 5
+ level: 3
+ }
+ }
+
+ DropArea {
+ id: serviceDropEnd
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ onDropped: (drag) => {
+ print("DROPPED AT END");
+ appendItem(dragItemTitle,
+ dragItemType,
+ dragItemBackground,
+ dragItemBackgroundType,
+ dragItemText,
+ dragItemIndex);
+ dropHighlightLine.visible = false;
+ }
+
+ keys: ["library"]
+
+ onEntered: (drag) => {
+ if (drag.keys[0] === "library") {
+ dropHighlightLine.visible = true;
+ var lastItem = serviceItemList.itemAtIndex(serviceItemModel.rowCount() - 1);
+ dropHighlightLine.y = lastItem.y + lastItem.height;
+ }
+ }
+
+ /* onExited: dropHighlightLine.visible = false; */
+
+ ListView {
+ id: serviceItemList
+ anchors.fill: parent
+ /* model: serviceItemModel */
+ /* delegate: Kirigami.DelegateRecycler { */
+ /* width: serviceItemList.width */
+ /* sourceComponent: itemDelegate */
+ /* } */
+ clip: true
+ spacing: 3
+ property int indexDragged
+ property int moveToIndex
+ property int draggedY
+
+ addDisplaced: Transition {
+ NumberAnimation {properties: "x, y"; duration: 100}
+ }
+ moveDisplaced: Transition {
+ NumberAnimation { properties: "x, y"; duration: 100 }
+ }
+ remove: Transition {
+ NumberAnimation { properties: "x, y"; duration: 100 }
+ NumberAnimation { properties: "opacity"; duration: 100 }
+ }
+
+ removeDisplaced: Transition {
+ NumberAnimation { properties: "x, y"; duration: 100 }
+ }
+
+ displaced: Transition {
+ NumberAnimation {properties: "x, y"; duration: 100}
+ }
+
+ model: serviceItemModel
+
+ delegate: DropArea {
+ id: serviceDrop
+ implicitWidth: serviceItemList.width
+ height: 50
+ /* enabled: false */
+
+ onEntered: (drag) => {
+ if (drag.keys[0] === "library") {
+ dropHighlightLine.visible = true;
+ dropHighlightLine.y = y - 2;
+ }
+ }
+
+ /* onExited: dropHighlightLine.visible = false; */
+
+ onDropped: (drag) => {
+ print("DROPPED IN ITEM AREA: " + drag.keys);
+ print(dragItemIndex + " " + index);
+ const hlIndex = serviceItemList.currentIndex;
+ if (drag.keys[0] === "library") {
+ addItem(index,
+ dragItemTitle,
+ dragItemType,
+ dragItemBackground,
+ dragItemBackgroundType,
+ dragItemText,
+ dragItemIndex);
+ } else if (drag.keys[0] === "serviceitem") {
+ serviceItemModel.move(serviceItemList.indexDragged,
+ serviceItemList.moveToIndex);
+ serviceItemList.currentIndex = moveToIndex;
+ }
+ dropHighlightLine.visible = false;
+ }
+
+ keys: ["library","serviceitem"]
+
+ Kirigami.BasicListItem {
+ id: visServiceItem
+ width: serviceDrop.width
+ height: serviceDrop.height
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ verticalCenter: parent.verticalCenter
+ }
+ label: name
+ subtitle: type
+ hoverEnabled: false
+ supportsMouseEvents: false
+ backgroundColor: {
+ if (serviceItemList.currentIndex === index)
+ Kirigami.Theme.highlightColor;
+ else if (mouseHandler.containsMouse)
+ Kirigami.Theme.hoverColor;
+ else
+ Kirigami.Theme.backgroundColor;
+ }
+ textColor: {
+ if (serviceItemList.currentIndex === index ||
+ mouseHandler.containsMouse)
+ activeTextColor;
+ else
+ Kirigami.Theme.textColor;
+ }
+
+ onYChanged: serviceItemList.updateDrag(Math.round(y));
+
+ states: [
+ State {
+ when: mouseHandler.drag.active
+ ParentChange {
+ target: visServiceItem
+ parent: serviceItemList
+ }
+
+ PropertyChanges {
+ target: visServiceItem
+ backgroundColor: Kirigami.Theme.backgroundColor
+ textColor: Kirigami.Theme.textColor
+ anchors.verticalCenter: undefined
+ anchors.horizontalCenter: undefined
+ }
+ }
+ ]
+
+ /* Drag.dragType: Drag.Automatic */
+ Drag.active: mouseHandler.drag.active
+ Drag.hotSpot.x: width / 2
+ Drag.hotSpot.y: height / 2
+ Drag.keys: ["serviceitem"]
+
+ MouseArea {
+ id: mouseHandler
+ anchors.fill: parent
+ hoverEnabled: true
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+ preventStealing: true
+
+ drag {
+ target: visServiceItem
+ axis: Drag.YAxis
+ /* minimumY: root.y */
+ /* maximumY: serviceItemList.height - serviceDrop.height */
+ smoothed: false
+ }
+
+ drag.onActiveChanged: {
+ if (mouseHandler.drag.active) {
+ serviceItemList.indexDragged = index;
+ }
+ }
+
+ /* onPositionChanged: { */
+ /* if (!pressed) { */
+ /* return; */
+ /* } */
+ /* mouseArea.arrangeItem(); */
+ /* } */
+
+ onPressed: {
+ serviceItemList.interactive = false;
+ }
+
+ onClicked: {
+ if (mouse.button === Qt.RightButton)
+ rightClickMenu.popup();
+ else {
+ serviceItemList.currentIndex = index;
+ /* currentServiceItem = index; */
+ /* changeItem(index); */
+ }
+ }
+
+ onDoubleClicked: {
+ showPassiveNotification("Double Clicked")
+ serviceItemList.currentIndex = index;
+ currentServiceItem = index;
+ changeServiceItem(index);
+ }
+
+ onReleased: {
+ print("should drop");
+ visServiceItem.Drag.drop();
+ }
+ }
+ }
+
+ Controls.Menu {
+ id: rightClickMenu
+ x: mouseHandler.mouseX
+ y: mouseHandler.mouseY + 10
+ Kirigami.Action {
+ text: "delete"
+ onTriggered: removeItem(index);
+ }
+ }
+ }
+
+
+ Kirigami.WheelHandler {
+ id: wheelHandler
+ target: serviceItemList
+ filterMouseEvents: true
+ keyNavigationEnabled: true
+ }
+
+ Controls.ScrollBar.vertical: Controls.ScrollBar {
+ anchors.right: serviceItemList.right
+ anchors.rightMargin: 0
+ active: hovered || pressed
+ }
+
+ function updateDrag(y) {
+ if (moveToIndex === serviceItemList.indexAt(0,y))
+ return;
+ else
+ moveToIndex = serviceItemList.indexAt(0,y);
+ moveRequested(indexDragged, moveToIndex);
+ }
+
+ function moveRequested(oldIndex, newIndex) {
+ if (newIndex === oldIndex)
+ return;
+ if (newIndex === -1)
+ newIndex = 0;
+ print("moveRequested: ", oldIndex, newIndex);
+ serviceItemModel.move(oldIndex, newIndex);
+ indexDragged = newIndex;
+ serviceItemList.currentIndex = newIndex;
+ }
+
+ }
+
+ Rectangle {
+ id: dropHighlightLine
+ width: parent.width
+ height: 4
+ color: Kirigami.Theme.hoverColor
+ visible: false
+
+ }
+ Canvas {
+ /* asynchronous: true; */
+ x: dropHighlightLine.width - 8
+ y: dropHighlightLine.y - 17
+ z: 1
+ width: 100; height: 100;
+ contextType: "2d"
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.fillStyle = Kirigami.Theme.hoverColor;
+ ctx.rotate(30);
+ ctx.transform(0.8, 0, 0, 0.8, 0, 30)
+ ctx.path = tearDropPath;
+ ctx.fill();
+ }
+ visible: dropHighlightLine.visible
+ }
+ Path {
+ id: tearDropPath
+ startX: dropHighlightLine.width
+ startY: dropHighlightLine.y + 4
+ PathSvg {
+ path: "M15 3
+ Q16.5 6.8 25 18
+ A12.8 12.8 0 1 1 5 18
+ Q13.5 6.8 15 3z"
+ }
+ }
+ }
+
+ Kirigami.ActionToolBar {
+ id: serviceToolBar
+ Layout.fillWidth: true
+ opacity: 1.0
+ actions: [
+ Kirigami.Action {
+ /* text: "Up" */
+ icon.name: "arrow-up"
+ onTriggered: {
+ const oldid = serviceItemList.currentIndex;
+ if (oldid <= 0)
+ {
+ showPassiveNotification("wow stop trying to go nego");
+ return;
+ }
+ const newid = serviceItemList.currentIndex - 1;
+ showPassiveNotification(oldid + " " + newid);
+ showPassiveNotification("Up");
+ const ans = serviceItemModel.move(oldid, newid);
+ if (ans)
+ {
+ serviceItemList.currentIndex = newid;
+ showPassiveNotification("move was successful, newid: "
+ + serviceItemList.currentIndex);
+ }
+ else
+ showPassiveNotification("move was unsuccessful")
+ }
+ },
+ Kirigami.Action {
+ /* text: "Down" */
+ icon.name: "arrow-down"
+ onTriggered: {
+ const oldid = serviceItemList.currentIndex;
+ if (oldid + 1 >= serviceItemList.count)
+ {
+ showPassiveNotification("wow you dummy you can't got further down");
+ return;
+ };
+ const newid = findId(serviceItemList.currentIndex + 2);
+ showPassiveNotification(oldid + " " + newid);
+ showPassiveNotification("Down");
+ const ans = serviceItemModel.move(oldid, newid);
+ if (ans)
+ {
+ serviceItemList.currentIndex = newid - 1;
+ showPassiveNotification("move was successful, newid: "
+ + serviceItemList.currentIndex);
+ }
+ else
+ showPassiveNotification("move was unsuccessful, newid: "
+ + newid);
+
+ function findId(id) {
+ if (id >= serviceItemList.count)
+ return serviceItemList.count;
+ else
+ return id;
+ }
+ }
+ },
+ Kirigami.Action {
+ /* text: "Remove" */
+ icon.name: "delete"
+ onTriggered: {
+ showPassiveNotification("remove");
+ removeItem(serviceItemList.currentIndex);
+ }
+ }
+ ]
+ }
+
+ Component.onCompleted: {
+ totalServiceItems = serviceItemList.count;
+ print("THE TOTAL SERVICE ITEMS: " + totalServiceItems);
+ }
+
+ function removeItem(index) {
+ serviceItemModel.removeItem(index);
+ totalServiceItems--;
+ }
+
+ function addItem(index, name, type,
+ background, backgroundType, text, itemID) {
+ const newtext = songsqlmodel.getLyricList(itemID);
+ print("adding: " + name + " of type " + type);
+ serviceItemModel.insertItem(index, name,
+ type, background,
+ backgroundType, newtext);
+ totalServiceItems++;
+ }
+
+ function appendItem(name, type, background, backgroundType, text, itemID) {
+ print("adding: " + name + " of type " + type);
+ let lyrics;
+ if (type === "song") {
+ print(itemID);
+ lyrics = songsqlmodel.getLyricList(itemID);
+ print(lyrics);
+ }
+
+ print(background);
+ print(backgroundType);
+
+ serviceItemModel.addItem(name, type, background,
+ backgroundType, lyrics);
+ totalServiceItems++;
+ }
+
+}
diff --git a/src/resources.qrc b/src/resources.qrc
index f7ef11d..7866e05 100644
--- a/src/resources.qrc
+++ b/src/resources.qrc
@@ -3,6 +3,7 @@
qml/main.qml
qml/presenter/qmldir
qml/presenter/LeftDock.qml
+ qml/presenter/ServiceList.qml
qml/presenter/MainWindow.qml
qml/presenter/Library.qml
qml/presenter/Header.qml
diff --git a/src/serviceitemmodel.cpp b/src/serviceitemmodel.cpp
index fe326b1..f97b83c 100644
--- a/src/serviceitemmodel.cpp
+++ b/src/serviceitemmodel.cpp
@@ -8,7 +8,7 @@
ServiceItemModel::ServiceItemModel(QObject *parent)
: QAbstractListModel(parent) {
- addItem(new ServiceItem("10,000 Resons", "song",
+ addItem(new ServiceItem("10,000 Reasons", "song",
"file:/home/chris/nextcloud/tfc/openlp/CMG - Nature King 21.jpg",
"image", QStringList("Yip Yip")));
addItem(new ServiceItem("Marvelous Light", "song",
@@ -114,6 +114,23 @@ Qt::ItemFlags ServiceItemModel::flags(const QModelIndex &index) const {
return Qt::ItemIsEditable; // FIXME: Implement me!
}
+// int ServiceItemModel::index(int row, int column, const QModelIndex &parent) {
+// if (!hasIndex(row, column, parent))
+// return QModelIndex();
+
+// ServiceItem *parentItem;
+
+// if (!parent.isValid())
+// parentItem = rootItem;
+// else
+// parentItem = static_cast(parent.internalPointer());
+
+// ServiceItem *childItem = parentItem->child(row);
+// if (childItem)
+// return createIndex(row, column, childItem);
+// return QModelIndex();
+// }
+
void ServiceItemModel::addItem(ServiceItem *item) {
const int index = m_items.size();
qDebug() << index;
@@ -181,23 +198,59 @@ void ServiceItemModel::removeItem(int index) {
bool ServiceItemModel::move(int sourceIndex, int destIndex) {
qDebug() << index(sourceIndex).row();
qDebug() << index(destIndex).row();
- // beginResetModel();
QModelIndex parent = index(sourceIndex).parent();
if (sourceIndex >= 0 && sourceIndex != destIndex &&
- destIndex >= -1 && destIndex < rowCount() &&
+ destIndex >= -1 && destIndex <= rowCount() &&
sourceIndex < rowCount()) {
qDebug() << "starting move: " << "source: " << sourceIndex << "dest: " << destIndex;
- bool begsuc = beginMoveRows(QModelIndex(), sourceIndex,
- sourceIndex, QModelIndex(), destIndex);
+ bool begsuc = beginMoveRows(parent, sourceIndex,
+ sourceIndex, parent, destIndex);
if (begsuc) {
- if (destIndex = -1)
- m_items.move(sourceIndex, 0);
+ if (destIndex == -1)
+ {
+ qDebug() << "dest was too small, moving to row 0";
+ m_items.move(sourceIndex, 0);
+ }
else
- m_items.move(sourceIndex, destIndex);
+ {
+ qDebug() << "dest was not too small";
+ if (destIndex >= m_items.size())
+ {
+ qDebug() << "destIndex too big, moving to end";
+ m_items.move(sourceIndex, m_items.size() - 1);
+ }
+ else
+ m_items.move(sourceIndex, destIndex);
+ }
endMoveRows();
+ return true;
}
+ qDebug() << "Can't move row, not sure why, sourceIndex: "
+ << sourceIndex << " destIndex: " << destIndex;
+ return false;
}
- return true;
+ qDebug() << "Can't move row, invalid options, sourceIndex: "
+ << sourceIndex << " destIndex: " << destIndex;
+ return false;
+}
+
+bool ServiceItemModel::move(int sourceIndex, int destIndex, bool simple) {
+ qDebug() << index(sourceIndex).row();
+ qDebug() << index(destIndex).row();
+ QModelIndex parent = index(sourceIndex).parent();
+
+ if (simple)
+ {
+ if (moveRow(parent, sourceIndex, parent, destIndex))
+ return true;
+ else
+ {
+ qDebug() << "not sure...";
+ return false;
+ }
+ }
+
+ return false;
}
QVariantMap ServiceItemModel::getItem(int index) const {
diff --git a/src/serviceitemmodel.h b/src/serviceitemmodel.h
index 4536b2c..1a76624 100644
--- a/src/serviceitemmodel.h
+++ b/src/serviceitemmodel.h
@@ -24,10 +24,15 @@ public:
// Basic functionality:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ // int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index,
int role = Qt::DisplayRole) const override;
QHash roleNames() const override;
+ // Q_INVOKABLE int index(int row, int column,
+ // const QModelIndex &parent = QModelIndex()) const override;
+ // Q_INVOKABLE QModelIndex parent(const QModelIndex &index) const override;
+
// Editable:
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole) override;
@@ -56,6 +61,7 @@ public:
const QString &backgroundType, const QStringList &text);
Q_INVOKABLE void removeItem(int index);
Q_INVOKABLE bool move(int sourceIndex, int destIndex);
+ Q_INVOKABLE bool move(int sourceIndex, int destIndex, bool simple);
Q_INVOKABLE QVariantMap getItem(int index) const;
private: