Song editor is functional and library adds new songs

This commit is contained in:
Chris Cochrun 2022-02-24 15:20:56 -06:00
parent f755190e40
commit b2ea6ab22a
6 changed files with 240 additions and 29 deletions

View file

@ -103,9 +103,43 @@ Item {
} }
} }
header: Component {
Kirigami.ActionToolBar {
height: selectedLibrary == "songs" ? 40 : 0
width: parent.width
display: IconOnly
actions: [
Kirigami.Action {
icon.name: "document-new"
text: "New Song"
tooltip: "Add a new song"
onTriggered: songLibraryList.newSong()
},
Kirigami.Action {
displayComponent: Component {
Kirigami.SearchField {
id: searchField
width: parent.width - 40
onAccepted: showPassiveNotification(searchField.text, 3000)
}
}
}
]
Behavior on height {
NumberAnimation {
easing.type: Easing.OutCubic
duration: 300
}
}
}
}
headerPositioning: ListView.OverlayHeader
Component { Component {
id: songDelegate id: songDelegate
Kirigami.BasicListItem { Kirigami.BasicListItem {
id: songListItem id: songListItem
implicitWidth: ListView.view.width implicitWidth: ListView.view.width
@ -114,6 +148,15 @@ Item {
label: title label: title
subtitle: author subtitle: author
hoverEnabled: true hoverEnabled: true
ListView.onAdd: {
showPassiveNotification(title, 3000)
songLibraryList.currentIndex = index
song = index
songTitle = title
songLyrics = lyrics
songAuthor = author
songVorder = vorder
}
Behavior on height { Behavior on height {
NumberAnimation { NumberAnimation {
@ -124,6 +167,7 @@ Item {
MouseArea { MouseArea {
id: dragHandler id: dragHandler
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
/* width: parent.width */ /* width: parent.width */
/* height: parent.height */ /* height: parent.height */
/* Layout.alignment: Qt.AlignTop */ /* Layout.alignment: Qt.AlignTop */
@ -139,12 +183,17 @@ Item {
} }
} }
onClicked: { onClicked: {
showPassiveNotification(title, 3000) if(mouse.button == Qt.RightButton)
songLibraryList.currentIndex = index showPassiveNotification("Delete me!");
song = index else{
songTitle = title showPassiveNotification(title, 3000)
songLyrics = lyrics songLibraryList.currentIndex = index
songAuthor = author song = index
songTitle = title
songLyrics = lyrics
songAuthor = author
songVorder = vorder
}
} }
} }
@ -176,6 +225,12 @@ Item {
anchors.leftMargin: 10 anchors.leftMargin: 10
active: hovered || pressed active: hovered || pressed
} }
function newSong() {
songsqlmodel.newSong();
songLibraryList.currentIndex = songsqlmodel.rowCount();
showPassiveNotification("newest song index: " + songLibraryList.currentIndex)
}
} }
Rectangle { Rectangle {

View file

@ -17,6 +17,7 @@ Controls.Page {
property string songTitle: "" property string songTitle: ""
property string songLyrics: "" property string songLyrics: ""
property string songAuthor: "" property string songAuthor: ""
property string songVorder: ""
property int blurRadius: 0 property int blurRadius: 0
property Item slideItem property Item slideItem
@ -145,10 +146,26 @@ Controls.Page {
} }
function updateLyrics(lyrics) { function updateLyrics(lyrics) {
showPassiveNotification("song id " + song); songsqlmodel.updateLyrics(song, lyrics);
}
songsqlmodel.setLyrics(song, lyrics); function updateTitle(title) {
songsqlmodel.updateTitle(song, title)
}
showPassiveNotification("did we do it?"); function updateAuthor(author) {
songsqlmodel.updateAuthor(song, author)
}
function updateAudio(audio) {
songsqlmodel.updateAudio(song, audio)
}
function updateCcli(ccli) {
songsqlmodel.updateCcli(song, ccli)
}
function updateVerseOrder(vorder) {
songsqlmodel.updateVerseOrder(song, vorder)
} }
} }

View file

@ -13,6 +13,7 @@ Item {
Presenter.Slide { Presenter.Slide {
id: representation id: representation
textSize: 48
editMode: true editMode: true
} }
} }

View file

@ -113,6 +113,20 @@ Item {
placeholderText: "Song Title..." placeholderText: "Song Title..."
text: songTitle text: songTitle
padding: 10 padding: 10
onEditingFinished: updateTitle(text);
}
Controls.TextField {
id: songVorderField
Layout.preferredWidth: 300
Layout.fillWidth: true
Layout.leftMargin: 20
Layout.rightMargin: 20
placeholderText: "verse order..."
text: songVorder
padding: 10
onEditingFinished: updateVerseOrder(text);
} }
Controls.ScrollView { Controls.ScrollView {
@ -126,15 +140,18 @@ Item {
rightPadding: 20 rightPadding: 20
Controls.TextArea { Controls.TextArea {
id: lyricsEditor
width: parent.width width: parent.width
placeholderText: "Put lyrics here..." placeholderText: "Put lyrics here..."
persistentSelection: true persistentSelection: true
text: songLyrics text: songLyrics
textFormat: TextEdit.MarkdownText textFormat: TextEdit.MarkdownText
padding: 10 padding: 10
onEditingFinished: mainPage.updateLyrics(text) onEditingFinished: {
/* onPressed: editorTimer.running = true */ updateLyrics(text);
editorTimer.running = false;
}
onPressed: editorTimer.running = true
} }
} }
Controls.TextField { Controls.TextField {
@ -148,6 +165,7 @@ Item {
placeholderText: "Author..." placeholderText: "Author..."
text: songAuthor text: songAuthor
padding: 10 padding: 10
onEditingFinished: updateAuthor(text)
} }
} }
@ -182,9 +200,9 @@ Item {
} }
Timer { Timer {
id: editorTimer id: editorTimer
interval: 2000 interval: 1000
repeat: true repeat: true
running: false running: false
onTriggered: showPassiveNotification("updating song...") onTriggered: updateLyrics(lyricsEditor.text)
} }
} }

View file

@ -22,27 +22,34 @@ static void createTable()
QSqlQuery query; QSqlQuery query;
if (!query.exec("CREATE TABLE IF NOT EXISTS 'songs' (" if (!query.exec("CREATE TABLE IF NOT EXISTS 'songs' ("
" 'id' INT NOT NULL,"
" 'title' TEXT NOT NULL," " 'title' TEXT NOT NULL,"
" 'lyrics' TEXT," " 'lyrics' TEXT,"
" 'author' TEXT," " 'author' TEXT,"
" 'ccli' TEXT," " 'ccli' TEXT,"
" 'audio' TEXT," " 'audio' TEXT,"
" PRIMARY KEY(title))")) { " 'vorder' TEXT,"
" PRIMARY KEY(id))")) {
qFatal("Failed to query database: %s", qFatal("Failed to query database: %s",
qPrintable(query.lastError().text())); qPrintable(query.lastError().text()));
} }
qDebug() << query.lastQuery();
qDebug() << "inserting into songs";
query.exec("INSERT INTO songs VALUES ('10,000 Reasons', '10,000 reasons for my heart to sing', 'Matt Redman', '13470183', '')"); query.exec("INSERT INTO songs VALUES (1, '10,000 Reasons', '10,000 reasons for my heart to sing', 'Matt Redman', '13470183', '', '')");
query.exec("INSERT INTO songs VALUES ('River', 'Im going down to the river', 'Jordan Feliz', '13470183', '')"); qDebug() << query.lastQuery();
query.exec("INSERT INTO songs VALUES ('Marvelous Light', 'Into marvelous light Im running', 'Chris Tomlin', '13470183', '')"); query.exec("INSERT INTO songs VALUES (2, 'River', 'Im going down to the river', 'Jordan Feliz', '13470183', '', '')");
query.exec("INSERT INTO songs VALUES (3, 'Marvelous Light', 'Into marvelous "
"light Im running', 'Chris Tomlin', '13470183', '', '')");
// query.exec("select * from songs"); query.exec("select * from songs");
// qDebug() << query.lastQuery(); qDebug() << query.lastQuery();
} }
SongSqlModel::SongSqlModel(QObject *parent) SongSqlModel::SongSqlModel(QObject *parent)
: QSqlTableModel(parent) : QSqlTableModel(parent)
{ {
qDebug() << "creating table";
createTable(); createTable();
setTable(songsTableName); setTable(songsTableName);
setEditStrategy(QSqlTableModel::OnFieldChange); setEditStrategy(QSqlTableModel::OnFieldChange);
@ -64,14 +71,38 @@ QVariant SongSqlModel::data(const QModelIndex &index, int role) const {
QHash<int, QByteArray> SongSqlModel::roleNames() const QHash<int, QByteArray> SongSqlModel::roleNames() const
{ {
QHash<int, QByteArray> names; QHash<int, QByteArray> names;
names[Qt::UserRole] = "title"; names[Qt::UserRole] = "id";
names[Qt::UserRole + 1] = "lyrics"; names[Qt::UserRole + 1] = "title";
names[Qt::UserRole + 2] = "author"; names[Qt::UserRole + 2] = "lyrics";
names[Qt::UserRole + 3] = "ccli"; names[Qt::UserRole + 3] = "author";
names[Qt::UserRole + 4] = "audio"; names[Qt::UserRole + 4] = "ccli";
names[Qt::UserRole + 5] = "audio";
names[Qt::UserRole + 6] = "vorder";
return names; return names;
} }
void SongSqlModel::newSong() {
qDebug() << "starting to add new song";
int rows = rowCount();
qDebug() << rows;
QSqlRecord recorddata = record(rows);
recorddata.setValue("id", rows + 1);
recorddata.setValue("title", "new song");
qDebug() << recorddata;
if (insertRecord(rows, recorddata)) {
submitAll();
select();
}else {
qDebug() << lastError();
}
}
int SongSqlModel::id() const {
return m_id;
}
QString SongSqlModel::title() const { QString SongSqlModel::title() const {
return m_title; return m_title;
} }
@ -86,6 +117,18 @@ void SongSqlModel::setTitle(const QString &title) {
emit titleChanged(); emit titleChanged();
} }
// This function is for updating the lyrics from outside the delegate
void SongSqlModel::updateTitle(const int &row, const QString &title) {
qDebug() << "Row is " << row;
QSqlRecord rowdata = record(row);
rowdata.setValue("title", title);
setRecord(row, rowdata);
submitAll();
select();
emit titleChanged();
}
QString SongSqlModel::author() const { QString SongSqlModel::author() const {
return m_author; return m_author;
} }
@ -100,6 +143,18 @@ void SongSqlModel::setAuthor(const QString &author) {
emit authorChanged(); emit authorChanged();
} }
// This function is for updating the lyrics from outside the delegate
void SongSqlModel::updateAuthor(const int &row, const QString &author) {
qDebug() << "Row is " << row;
QSqlRecord rowdata = record(row);
rowdata.setValue("author", author);
setRecord(row, rowdata);
submitAll();
select();
emit authorChanged();
}
QString SongSqlModel::lyrics() const { QString SongSqlModel::lyrics() const {
return m_lyrics; return m_lyrics;
} }
@ -114,7 +169,8 @@ void SongSqlModel::setLyrics(const QString &lyrics) {
emit lyricsChanged(); emit lyricsChanged();
} }
void SongSqlModel::setLyrics(const int &row, const QString &lyrics) { // This function is for updating the lyrics from outside the delegate
void SongSqlModel::updateLyrics(const int &row, const QString &lyrics) {
qDebug() << "Row is " << row; qDebug() << "Row is " << row;
QSqlRecord rowdata = record(row); QSqlRecord rowdata = record(row);
rowdata.setValue("lyrics", lyrics); rowdata.setValue("lyrics", lyrics);
@ -123,7 +179,6 @@ void SongSqlModel::setLyrics(const int &row, const QString &lyrics) {
select(); select();
emit lyricsChanged(); emit lyricsChanged();
} }
QString SongSqlModel::ccli() const { QString SongSqlModel::ccli() const {
@ -140,6 +195,18 @@ void SongSqlModel::setCcli(const QString &ccli) {
emit ccliChanged(); emit ccliChanged();
} }
// This function is for updating the lyrics from outside the delegate
void SongSqlModel::updateCcli(const int &row, const QString &ccli) {
qDebug() << "Row is " << row;
QSqlRecord rowdata = record(row);
rowdata.setValue("ccli", ccli);
setRecord(row, rowdata);
submitAll();
select();
emit ccliChanged();
}
QString SongSqlModel::audio() const { QString SongSqlModel::audio() const {
return m_audio; return m_audio;
} }
@ -153,3 +220,39 @@ void SongSqlModel::setAudio(const QString &audio) {
select(); select();
emit audioChanged(); emit audioChanged();
} }
// This function is for updating the lyrics from outside the delegate
void SongSqlModel::updateAudio(const int &row, const QString &audio) {
qDebug() << "Row is " << row;
QSqlRecord rowdata = record(row);
rowdata.setValue("audio", audio);
setRecord(row, rowdata);
submitAll();
select();
emit audioChanged();
}
QString SongSqlModel::vorder() const { return m_vorder; }
void SongSqlModel::setVerseOrder(const QString &vorder) {
if (vorder == m_vorder)
return;
m_vorder = vorder;
select();
emit vorderChanged();
}
// This function is for updating the lyrics from outside the delegate
void SongSqlModel::updateVerseOrder(const int &row, const QString &vorder) {
qDebug() << "Row is " << row;
QSqlRecord rowdata = record(row);
rowdata.setValue("vorder", vorder);
setRecord(row, rowdata);
submitAll();
select();
emit vorderChanged();
}

View file

@ -3,34 +3,48 @@
#include <QSqlTableModel> #include <QSqlTableModel>
#include <qabstractitemmodel.h> #include <qabstractitemmodel.h>
#include <qobjectdefs.h>
#include <qqml.h> #include <qqml.h>
#include <qvariant.h> #include <qvariant.h>
class SongSqlModel : public QSqlTableModel class SongSqlModel : public QSqlTableModel
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int id READ id)
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged) Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
Q_PROPERTY(QString lyrics READ lyrics WRITE setLyrics NOTIFY lyricsChanged) Q_PROPERTY(QString lyrics READ lyrics WRITE setLyrics NOTIFY lyricsChanged)
Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged) Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
Q_PROPERTY(QString ccli READ ccli WRITE setCcli NOTIFY ccliChanged) Q_PROPERTY(QString ccli READ ccli WRITE setCcli NOTIFY ccliChanged)
Q_PROPERTY(QString audio READ audio WRITE setAudio NOTIFY audioChanged) Q_PROPERTY(QString audio READ audio WRITE setAudio NOTIFY audioChanged)
Q_PROPERTY(QString vorder READ vorder WRITE setVerseOrder NOTIFY vorderChanged)
QML_ELEMENT QML_ELEMENT
public: public:
SongSqlModel(QObject *parent = 0); SongSqlModel(QObject *parent = 0);
int id() const;
QString title() const; QString title() const;
QString lyrics() const; QString lyrics() const;
QString author() const; QString author() const;
QString ccli() const; QString ccli() const;
QString audio() const; QString audio() const;
QString vorder() const;
void setTitle(const QString &title); void setTitle(const QString &title);
void setLyrics(const QString &lyrics); void setLyrics(const QString &lyrics);
void setLyrics(const int &row, const QString &lyrics);
void setAuthor(const QString &author); void setAuthor(const QString &author);
void setCcli(const QString &ccli); void setCcli(const QString &ccli);
void setAudio(const QString &audio); void setAudio(const QString &audio);
void setVerseOrder(const QString &vorder);
Q_INVOKABLE void updateTitle(const int &row, const QString &title);
Q_INVOKABLE void updateLyrics(const int &row, const QString &lyrics);
Q_INVOKABLE void updateAuthor(const int &row, const QString &author);
Q_INVOKABLE void updateCcli(const int &row, const QString &ccli);
Q_INVOKABLE void updateAudio(const int &row, const QString &audio);
Q_INVOKABLE void updateVerseOrder(const int &row, const QString &vorder);
Q_INVOKABLE void newSong();
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
@ -41,13 +55,16 @@ signals:
void authorChanged(); void authorChanged();
void ccliChanged(); void ccliChanged();
void audioChanged(); void audioChanged();
void vorderChanged();
private: private:
int m_id;
QString m_title; QString m_title;
QString m_lyrics; QString m_lyrics;
QString m_author; QString m_author;
QString m_ccli; QString m_ccli;
QString m_audio; QString m_audio;
QString m_vorder;
}; };
#endif //SONGSQLMODEL_H #endif //SONGSQLMODEL_H