qml logick complite

This commit is contained in:
Andrei Yankovich 2018-03-10 16:38:56 +03:00
parent 910d94dbcb
commit 9bfff58222
16 changed files with 349 additions and 131 deletions

View File

@ -40,7 +40,7 @@ Item {
function map(obj){
var index = selectedFiles.indexOf(obj);
if(index === -1){
selectedFiles.push(obj);
selectedFiles.push(folderListModel.folder + "/" + obj);
return true;
}else{
selectedFiles.splice(index,1);

View File

@ -1,5 +1,8 @@
import QtQuick 2.4
import QtQuick.Controls 2.0
import QtQuick.Extras 1.4
import QtQuick.Window 2.0
import "./base" as Base
import "base/utils.js" as Utils
@ -7,93 +10,153 @@ Rectangle {
id: playListPane;
property string name: "no selected"
property var selectedSongs : []
readonly property real rowHeight: Utils.dp(Screen.pixelDensity, 36)
readonly property real rowWidth: parent.width;
readonly property real textmargin: Utils.dp(Screen.pixelDensity, 8)
readonly property real textSize: Utils.dp(Screen.pixelDensity, 10)
readonly property real buttonHeight: Utils.dp(Screen.pixelDensity, 24)
function showPlayList(name){
playListModel.setNewList(name);
this.name = name;
}
signal select();
color: Utils.backgroundColor()
Base.BaseText{
id:namePalyList
height: 30
text: (parent.name)
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
}
Item{
id: buttons;
height: 30
Button{
id: ok
text: qsTr("ok")
onClicked: {
for(var i = 0; i < model.count; i++ ){
if(model.get(i).isSelected){
selectedSongs.push(model.get(i).getName());
}
}
select();
switch_pane(playListsControlSource);
}
anchors.left: parent.left
anchors.leftMargin: 10
}
Button{
id: cancel;
text: qsTr("cancel")
onClicked: {
switch_pane(playListsControlSource);
}
anchors.left: ok.right
anchors.leftMargin: 10;
}
Button{
id: add;
text: qsTr("add")
onClicked: {
switch_pane(fileDialog);
}
anchors.right: remove.left
anchors.rightMargin: 10
}
Button{
id: remove;
text: qsTr("remove")
onClicked: {
}
anchors.right: parent.right
anchors.rightMargin: 10
}
anchors.bottom: listView.top
anchors.left: parent.left
anchors.right: parent.right
}
ListView {
id: listView
model: ListModel {
id: model
model: playListModel
Component {
id: playListDelegate
Item {
height: rowHeight
width: listView.width
id: item
Rectangle {
color: Utils.baseColor();
id: rectangle;
anchors.fill: item
MouseArea {
anchors.fill: parent;
onClicked: {
indicator.active = playListModel.select(songId)
}
}
Text {
id: textNameSong
height: width
anchors.left: image.right
anchors.top: rectangle.top
anchors.bottom: rectangle.bottom
anchors.right: indicator.left
text: songName !== undefined ? songName : ""
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
StatusIndicator{
id: indicator
width: height * 0.9
color: "#4fc1e9"
active: playListModel.isSelected(songId);
anchors.right: rectangle.right
anchors.leftMargin: textmargin
anchors.verticalCenter: rectangle.verticalCenter
}
Image {
id: image
height: buttonHeight
width: height
anchors.left: rectangle.left
anchors.leftMargin: textmargin
anchors.verticalCenter: rectangle.verticalCenter
source: "image://collection/" + songId
}
}
}
}
// delegate: SongDelegateSelection{
delegate: playListDelegate
// }
anchors.top:name.bottom
anchors.bottom: buttons.bottom
ScrollIndicator.horizontal: ScrollIndicator { }
ScrollIndicator.vertical: ScrollIndicator { }
anchors.top:controlBox.bottom
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
}
Rectangle{
id:controlBox
color: Utils.baseColor()
height: Utils.dp(Screen.pixelDensity, 40)
Base.BaseText{
id:namePalyList
text: playListPane.name
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: buttons.left
}
Rectangle{
id: buttons;
height: namePalyList.height
color: Utils.baseColor()
width: Utils.dp(Screen.pixelDensity, 160)
Base.BaseButton{
id: ok
text: qsTr("ok")
onClicked: {
switch_pane(playListsControlSource);
}
anchors.left: add.right
anchors.right: parent.right
}
Base.BaseButton{
id: add;
text: qsTr("add")
onClicked: {
switch_pane(fileDialog);
}
anchors.left: parent.left
anchors.rightMargin: 10
}
anchors.right: parent.right
}
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
}
}

View File

@ -77,18 +77,20 @@ Item {
anchors.top: parent.top
onClicked: {
switch_pane(editPlayList);
popup.close()
editPlayList.showPlayList(playListName);
popup.close();
}
}
Button {
text: qsTr("Remove")
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: parent.height/2
text: qsTr("Remove");
anchors.left: parent.left;
anchors.right: parent.right;
anchors.bottom: parent.bottom;
height: parent.height/2;
onClicked: {
popup.close()
syncEngine.removePlayList(playListName);
popup.close();
}
}
@ -153,6 +155,7 @@ Item {
anchors.bottom: parent.bottom
onClicked: {
getName.open();
}
@ -165,6 +168,67 @@ Item {
anchors.fill: playListsControl;
}
Popup{
id:getName
modal: true
focus: true
width: controlBox.width;
height: Utils.dp(Screen.pixelDensity, 60);
x: 0;
y: controlBox.height / 2
Base.BaseText{
id:text
text : qsTr("write name:");
anchors.left: parent.left;
anchors.top:parent.top;
anchors.bottom:parent.bottom;
}
Rectangle{
color: Qt.rgba(0,0,0,0)
border.color: Utils.primaryColor();
radius: Utils.dp(Screen.pixelDensity, 2);
TextEdit{
id:newName;
text : qsTr("new PlayList");
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.pixelSize: Utils.baseFontSize(Screen.pixelDensity)
anchors.fill: parent
}
anchors.top:parent.top;
anchors.topMargin: Utils.dp(Screen.pixelDensity, 5);
anchors.bottom:parent.bottom;
anchors.bottomMargin: Utils.dp(Screen.pixelDensity, 5);
anchors.left:text.right
anchors.leftMargin: Utils.dp(Screen.pixelDensity, 10);
anchors.right: ok.left
anchors.rightMargin: Utils.dp(Screen.pixelDensity, 10);
}
Base.BaseButton{
id:ok;
width: 80;
anchors.top:parent.top;
anchors.bottom:parent.bottom;
anchors.right: parent.right;
onClicked: {
syncEngine.createPlayList(newName.text);
getName.close();
}
}
}
PlayListEditPane{
@ -183,8 +247,11 @@ Item {
nameFilters: "*.mp3"
onFilesSelected: {
switch_pane(editPlayList);
// messageDialog.text = "Cannot open file "+ currentFolder() + "/" + fileName
// messageDialog.open()
for(var i = 0; i < selectedFiles.length; i++){
syncEngine.addSong(selectedFiles[i]);
}
}
}

View File

@ -23,6 +23,9 @@ App::App(QObject* ptr):
currentPlayListModel = new CurrentPlayListModel();
currentPlayListModel->setSource(syncEngine);
playListModel = new PlayListModel();
playListModel->setSource(syncEngine);
}
bool App::run(){
@ -34,6 +37,8 @@ bool App::run(){
ctxt->setContextProperty("serverListModel", serverListModel);
ctxt->setContextProperty("playListsModel", playListsModel);
ctxt->setContextProperty("currentPlayListModel", currentPlayListModel);
ctxt->setContextProperty("playListModel", playListModel);
qmlEngine->load(QUrl(QStringLiteral("qrc:/main.qml")));
if (qmlEngine->rootObjects().isEmpty())

View File

@ -26,6 +26,8 @@ private:
ServerListModel *serverListModel;
PlayListsModel *playListsModel;
CurrentPlayListModel *currentPlayListModel;
PlayListModel *playListModel;
public:

View File

@ -0,0 +1,12 @@
import QtQuick 2.4
import QtQuick.Controls 2.0
import QtQuick.Window 2.0
import "utils.js" as Utils
Button{
id: ok
text: qsTr("ok")
width: Utils.dp(Screen.pixelDensity, 80)
height: Utils.dp(Screen.pixelDensity, 40)
}

View File

@ -1,3 +1,4 @@
function dp(pixelDensity,x) {
return (pixelDensity * 25.4 < 120) ? x : x*(pixelDensity * 25.4/160);
}
@ -26,3 +27,7 @@ function backgroundAltColor() {
return "#333333"
}
function baseFontSize(pixelDensity){
return dp(pixelDensity, 14);
}

View File

@ -36,7 +36,7 @@ void CurrentPlayListModel::onPlayListChanged(){
bool CurrentPlayListModel::canFetchMore(const QModelIndex & /* index */) const
{
if (playList && itemCount < playList->size())
if (playList && itemCount != playList->size())
return true;
else
return false;
@ -47,11 +47,19 @@ void CurrentPlayListModel::fetchMore(const QModelIndex & /* index */)
int remainder = playList->size() - itemCount;
int itemsToFetch = qMin(100, remainder);
beginInsertRows(QModelIndex(), itemCount, itemCount + itemsToFetch - 1);
if(itemsToFetch < 0){
beginRemoveRows(QModelIndex(), 0, 0 - itemsToFetch - 1 );
itemCount += itemsToFetch;
itemCount += itemsToFetch;
endInsertRows();
endRemoveRows();
}else{
beginInsertRows(QModelIndex(), itemCount, itemCount + itemsToFetch - 1);
itemCount += itemsToFetch;
endInsertRows();
}
}
int CurrentPlayListModel::rowCount(const QModelIndex & /* parent */) const

View File

@ -15,6 +15,7 @@ void PlayListModel::setSource(SyncEngine *engine){
disconnect(syncEngine, SIGNAL(songsCountChanged()) ,this, SLOT(onPlayListChanged()));
syncEngine = engine;
connect(syncEngine, SIGNAL(songsCountChanged()),this ,SLOT(onPlayListChanged()));
onPlayListChanged();
}
QHash<int, QByteArray> PlayListModel::roleNames()const{
@ -37,7 +38,7 @@ void PlayListModel::onPlayListChanged(){
bool PlayListModel::canFetchMore(const QModelIndex & /* index */) const
{
if (itemCount < playList.size())
if (itemCount != playList.size())
return true;
else
return false;
@ -48,11 +49,20 @@ void PlayListModel::fetchMore(const QModelIndex & /* index */)
int remainder = playList.size() - itemCount;
int itemsToFetch = qMin(100, remainder);
beginInsertRows(QModelIndex(), itemCount, itemCount + itemsToFetch - 1);
if(itemsToFetch < 0){
beginRemoveRows(QModelIndex(), 0, 0 - itemsToFetch - 1 );
itemCount += itemsToFetch;
itemCount += itemsToFetch;
endRemoveRows();
}else{
beginInsertRows(QModelIndex(), itemCount, itemCount + itemsToFetch - 1);
itemCount += itemsToFetch;
endInsertRows();
}
endInsertRows();
}
int PlayListModel::rowCount(const QModelIndex & /* parent */) const
@ -84,21 +94,17 @@ QVariant PlayListModel::data(const QModelIndex &index, int role) const
bool PlayListModel::select(int id){
for(QList<syncLib::SongHeader>::Iterator i = 0; i < playList.end(); i++){
for(QList<syncLib::SongHeader>::Iterator i = playList.begin(); i < playList.end(); i++){
if(i->id == id){
return i->isSelected = true;
}
}
return false;
}
if((i->isSelected = !i->isSelected)){
syncEngine->addToPlayList(id, playListName);
}
else{
syncEngine->removeFromPlayList(id, playListName);
}
bool PlayListModel::unSelect(int id){
for(QList<syncLib::SongHeader>::Iterator i = 0; i < playList.end(); i++){
if(i->id == id){
i->isSelected = false;
return true;
return i->isSelected;
}
}
@ -108,7 +114,7 @@ bool PlayListModel::unSelect(int id){
QList<int> PlayListModel::getSelected(){
QList<int> result;
for(QList<syncLib::SongHeader>::Iterator i = 0; i < playList.end(); i++){
for(QList<syncLib::SongHeader>::Iterator i = playList.begin(); i < playList.end(); i++){
if(i->isSelected){
result.push_back(i->id);
}
@ -118,7 +124,7 @@ QList<int> PlayListModel::getSelected(){
bool PlayListModel::isSelected(int id){
for(QList<syncLib::SongHeader>::Iterator i = 0; i < playList.end(); i++){
for(QList<syncLib::SongHeader>::Iterator i = playList.begin(); i < playList.end(); i++){
if(i->id == id){
return i->isSelected;
}

View File

@ -74,19 +74,12 @@ signals:
public slots:
/**
* @brief select a song from playList;
* @brief select a song from playList or unselected if item has been selected;
* @param id - if of song
* @return true if all done
*/
bool select(int id);
/**
* @brief unselect a song from playList;
* @param id - if of song
* @return true if all done
*/
bool unSelect(int id);
/**
* @brief getSelected
* @return list of selected songs

View File

@ -31,7 +31,7 @@ void PlayListsModel::onPlayListsChanged(){
bool PlayListsModel::canFetchMore(const QModelIndex & /* index */) const
{
if (itemCount < playLists.size())
if (itemCount != playLists.size())
return true;
else
return false;
@ -42,11 +42,20 @@ void PlayListsModel::fetchMore(const QModelIndex & /* index */)
int remainder = playLists.size() - itemCount;
int itemsToFetch = qMin(100, remainder);
beginInsertRows(QModelIndex(), itemCount, itemCount + itemsToFetch - 1);
if(itemsToFetch < 0){
beginRemoveRows(QModelIndex(), 0, 0 - itemsToFetch - 1 );
itemCount += itemsToFetch;
itemCount += itemsToFetch;
endRemoveRows();
}else{
beginInsertRows(QModelIndex(), itemCount, itemCount + itemsToFetch - 1);
itemCount += itemsToFetch;
endInsertRows();
}
endInsertRows();
}
int PlayListsModel::rowCount(const QModelIndex & /* parent */) const

View File

@ -13,6 +13,7 @@
<file>FileDialog.qml</file>
<file>base/utils.js</file>
<file>base/StatusIndicator.qml</file>
<file>base/BaseButton.qml</file>
</qresource>
<qresource prefix="/image">
<file>res/logo.png</file>

View File

@ -30,7 +30,7 @@ void ServerListModel::onServersListsChanged(){
bool ServerListModel::canFetchMore(const QModelIndex & /* index */) const
{
if (servers && itemCount < servers->size())
if (servers && itemCount != servers->size())
return true;
else
return false;
@ -41,11 +41,19 @@ void ServerListModel::fetchMore(const QModelIndex & /* index */)
int remainder = servers->size() - itemCount;
int itemsToFetch = qMin(100, remainder);
beginInsertRows(QModelIndex(), itemCount, itemCount + itemsToFetch - 1);
if(itemsToFetch < 0){
beginRemoveRows(QModelIndex(), 0, 0 - itemsToFetch - 1 );
itemCount += itemsToFetch;
itemCount += itemsToFetch;
endInsertRows();
endRemoveRows();
}else{
beginInsertRows(QModelIndex(), itemCount, itemCount + itemsToFetch - 1);
itemCount += itemsToFetch;
endInsertRows();
}
}
int ServerListModel::rowCount(const QModelIndex & /* parent */) const

View File

@ -164,7 +164,7 @@ bool SyncEngine::setPlayList(const QString& name){
}
bool SyncEngine::getPlayList(QList<syncLib::SongHeader> &playList, const QString &name){
return sqlApi->updateAvailableSongs(playList, name);
return sqlApi->updateAvailableSongs(playList, name, true);
}
const QString& SyncEngine::lastError() const{

View File

@ -50,7 +50,20 @@ void MySql::initDB(const QString &database){
db->setDatabaseName(d.absolutePath());
if(db->open()){
qyery = new QSqlQuery(*db);
QString qyer = QString("CREATE TABLE IF NOT EXISTS songs("
/*
*https://stackoverflow.com/questions/40863216/sqlite-why-is-foreign-key-constraint-not-working-here
*/
QString qyer = QString("PRAGMA foreign_keys = ON");
if(!qyery->exec(qyer)){
sqlErrorLog(qyer);
throw InitDBError();
delete db;
return;
}
qyer = QString("CREATE TABLE IF NOT EXISTS songs("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name VARCHAR(100), "
"size INT NOT NULL, "
@ -63,6 +76,7 @@ void MySql::initDB(const QString &database){
return;
}
qyer = QString("CREATE UNIQUE INDEX IF NOT EXISTS isongs ON songs(name,size)");
if(!qyery->exec(qyer)){
sqlErrorLog(qyer);
@ -87,7 +101,7 @@ void MySql::initDB(const QString &database){
qyer = QString("CREATE TABLE IF NOT EXISTS playlistsdata("
"playlist INT NOT NULL,"
"song INT NOT NULL,"
"FOREIGN KEY(playlist) REFERENCES playlists(id)"
"FOREIGN KEY(playlist) REFERENCES playlists(name)"
" ON UPDATE CASCADE"
" ON DELETE CASCADE,"
"FOREIGN KEY(song) REFERENCES songs(id)"
@ -155,8 +169,8 @@ int MySql::save(const Song &song){
return result;
}
int MySql::save(const QString &url){
QFile f(url);
int MySql::save(const QString &url){
QFile f(QUrl(url).toLocalFile());
if(!f.open(QIODevice::ReadOnly)){
return -1;
}
@ -203,9 +217,10 @@ bool MySql::load(const SongHeader &song,Song &result){
return true;
}
bool MySql::updateAvailableSongs(QList<SongHeader>& list, const QString& playList){
bool MySql::updateAvailableSongs(QList<SongHeader>& list, const QString& playList, bool forEditing){
QString qyer;
if(playList.isEmpty() || playList == ALL_SONGS_LIST){
if(playList.isEmpty() || playList == ALL_SONGS_LIST || forEditing){
qyer = QString("SELECT id,name,size from songs");
}else{
qyer = QString("SELECT id,name,size from songs where "
@ -222,12 +237,35 @@ bool MySql::updateAvailableSongs(QList<SongHeader>& list, const QString& playLis
while(qyery->next()){
SongHeader song;
song.isSelected = !forEditing || playList == ALL_SONGS_LIST;
song.id = qyery->value(0).toInt();
song.name = qyery->value(1).toString();
song.size = qyery->value(2).toInt();
list.push_back(song);
}
if(forEditing && list.size() > 0 && playList != ALL_SONGS_LIST){
QString qyer;
qyer = QString("select song from playlistsdata where "
" playlist='%0'").arg(playList);
if(!qyery->exec(qyer)){
sqlErrorLog(qyer);
return false;
}
while(qyery->next()){
for(SongHeader& item:list){
int id = qyery->value(0).toInt();
if(item.id == id){
item.isSelected = true;
break;
}
}
}
}
return true;
}

View File

@ -59,9 +59,10 @@ public:
* @brief updateAvelableSongs will update the list of participants of songs.
* @param list - [out value] list of avelable song.
* @param playList - play list of songs.
* @param forEdit - flag for editing play list. If this flag = true then return all available songs with corect flag 'isSelect'
* @return true if all done
*/
bool updateAvailableSongs(QList<SongHeader>& list, const QString &playList = "");
bool updateAvailableSongs(QList<SongHeader>& list, const QString &playList = "", bool forEditing = false);
/**
* @brief updateAvelableSongs will update the list of participants of songs.