Add support for folders tab
This commit is contained in:
committed by
craig.p.drummond@gmail.com
parent
5de31f5d8f
commit
e5da87c7de
@@ -25,11 +25,19 @@
|
||||
#include "stdactions.h"
|
||||
#include "itemview.h"
|
||||
|
||||
#ifdef ENABLE_UBUNTU
|
||||
static const int Role_HasChildren = Qt::UserRole+500;
|
||||
#endif
|
||||
|
||||
QVariant ActionModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
QVariant v;
|
||||
#ifdef ENABLE_UBUNTU
|
||||
if (Role_HasChildren==role) {
|
||||
return rowCount(index)>0;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(index)
|
||||
#ifndef ENABLE_UBUNTU // Should touch version return a list of action names?
|
||||
if (ItemView::Role_Actions==role) {
|
||||
v.setValue<QList<Action *> >(QList<Action *>() << StdActions::self()->replacePlayQueueAction << StdActions::self()->addToPlayQueueAction);
|
||||
}
|
||||
@@ -46,6 +54,7 @@ QHash<int, QByteArray> ActionModel::roleNames() const
|
||||
roles[ItemView::Role_SubText] = "subText";
|
||||
roles[ItemView::Role_TitleText] = "titleText";
|
||||
roles[ItemView::Role_Image] = "image";
|
||||
roles[Role_HasChildren] = "hasChildren";
|
||||
return roles;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -186,6 +186,17 @@ QVariant DirViewModel::data(const QModelIndex &index, int role) const
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_UBUNTU
|
||||
case ItemView::Role_TitleText:
|
||||
switch (item->type()) {
|
||||
case DirViewItem::Type_Dir:
|
||||
return static_cast<DirViewItemDir *>(item)->fullName();
|
||||
default:
|
||||
case DirViewItem::Type_File:
|
||||
return item->data();
|
||||
}
|
||||
#endif
|
||||
case ItemView::Role_MainText:
|
||||
case Qt::DisplayRole:
|
||||
return item->data();
|
||||
case Qt::ToolTipRole:
|
||||
@@ -427,6 +438,10 @@ void DirViewModel::updateDirView(DirViewItemRoot *newroot, const QDateTime &dbUp
|
||||
if (!fromFile && (needToSave || updatedListing)) {
|
||||
toXML();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_UBUNTU
|
||||
emit updated();
|
||||
#endif
|
||||
}
|
||||
|
||||
void DirViewModel::updatingMpd()
|
||||
|
||||
@@ -67,6 +67,9 @@ public Q_SLOTS:
|
||||
void updateDirView(DirViewItemRoot *newroot, const QDateTime &dbUpdate=QDateTime(), bool fromFile=false);
|
||||
void updatingMpd();
|
||||
|
||||
Q_SIGNALS:
|
||||
void updated();
|
||||
|
||||
private:
|
||||
void toXML(const DirViewItem *item, QXmlStreamWriter &writer);
|
||||
quint32 fromXML(QIODevice *dev, const QDateTime &dt, DirViewItemRoot *root);
|
||||
|
||||
@@ -41,12 +41,19 @@ MPDBackend::MPDBackend(QObject *parent) : QObject(parent)
|
||||
connect(this, SIGNAL(goToNextSong()), MPDConnection::self(), SLOT(goToNext()));
|
||||
connect(this, SIGNAL(goToPreviousSong()), MPDConnection::self(), SLOT(goToPrevious()));
|
||||
connect(this, SIGNAL(loadLibrary()), MPDConnection::self(), SLOT(loadLibrary()));
|
||||
connect(this, SIGNAL(loadFolders()), MPDConnection::self(), SLOT(loadFolders()));
|
||||
|
||||
connect(MPDConnection::self(), SIGNAL(stateChanged(bool)), this, SLOT(onConnected(bool)));
|
||||
|
||||
// TODO: These need to be confiurable vi QML UI!
|
||||
AlbumsModel::self()->setEnabled(true);
|
||||
DirViewModel::self()->setEnabled(true);
|
||||
PlaylistsModel::self()->setEnabled(true);
|
||||
|
||||
playQueueProxyModel.setSourceModel(&playQueueModel);
|
||||
artistsProxyModel.setSourceModel(MusicLibraryModel::self());
|
||||
albumsProxyModel.setSourceModel(AlbumsModel::self());
|
||||
foldersProxyModel.setSourceModel(DirViewModel::self());
|
||||
playlistsProxyModel.setSourceModel(PlaylistsModel::self());
|
||||
|
||||
// connect(MPDConnection::self(), SIGNAL(outputsUpdated(const QList<Output> &)), this, SLOT(outputsUpdated(const QList<Output> &)));
|
||||
@@ -96,6 +103,7 @@ MPDBackend::MPDBackend(QObject *parent) : QObject(parent)
|
||||
|
||||
connect(MusicLibraryModel::self(), SIGNAL(updated()), this, SLOT(artistsUpdated()));
|
||||
connect(AlbumsModel::self(), SIGNAL(updated()), this, SLOT(albumsUpdated()));
|
||||
connect(DirViewModel::self(), SIGNAL(updated()), this, SLOT(foldersUpdated()));
|
||||
connect(PlaylistsModel::self(), SIGNAL(updated()), this, SLOT(playlistsUpdated()));
|
||||
|
||||
MPDConnection::self()->start();
|
||||
@@ -157,20 +165,25 @@ void MPDBackend::setIsRandomOrder(bool random) {
|
||||
emit setRandomOrder(random);
|
||||
}
|
||||
|
||||
// TODO: Why are the sorts required below? e.g. If we don't call sort, the items are only sorted string-wise. This
|
||||
// means that 'Various Artists' is not placed at the top, and "The XXX" is not sorted as "XXX"
|
||||
void MPDBackend::artistsUpdated() {
|
||||
// TODO: If we don't call sort here, the items are only sorted string-wise. This
|
||||
// means that 'Various Artists' is not placed at the top, and "The XXX" is not sorted as "XXX"
|
||||
artistsProxyModel.sort();
|
||||
emit onArtistsModelChanged();
|
||||
}
|
||||
|
||||
void MPDBackend::albumsUpdated() {
|
||||
//albumsProxyModel.sort();
|
||||
albumsProxyModel.sort();
|
||||
emit onAlbumsModelChanged();
|
||||
}
|
||||
|
||||
void MPDBackend::foldersUpdated() {
|
||||
foldersProxyModel.sort();
|
||||
emit onFoldersModelChanged();
|
||||
}
|
||||
|
||||
void MPDBackend::playlistsUpdated() {
|
||||
//playlistsProxyModel.sort();
|
||||
playlistsProxyModel.sort();
|
||||
emit onPlaylistsModelChanged();
|
||||
}
|
||||
|
||||
@@ -183,9 +196,12 @@ void MPDBackend::add(const QString &modelName, const QVariant &rows, bool replac
|
||||
} else if ("albums"==modelName) {
|
||||
proxy=&albumsProxyModel;
|
||||
model=AlbumsModel::self();
|
||||
} else if ("playlists"==modelName) {
|
||||
} else if ("playlists"==modelName) {
|
||||
proxy=&playlistsProxyModel;
|
||||
model=PlaylistsModel::self();
|
||||
} else if ("folders"==modelName) {
|
||||
proxy=&foldersProxyModel;
|
||||
model=DirViewModel::self();
|
||||
}
|
||||
|
||||
if (model) {
|
||||
@@ -324,6 +340,9 @@ void MPDBackend::updateStats() //Does nothing right now...
|
||||
if (!MusicLibraryModel::self()->fromXML()) {
|
||||
emit loadLibrary();
|
||||
}
|
||||
if (DirViewModel::self()->isEnabled() && !DirViewModel::self()->fromXML()) {
|
||||
emit loadFolders();
|
||||
}
|
||||
// albumsPage->goTop();
|
||||
// libraryPage->refresh();
|
||||
// folderPage->refresh();
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include "musiclibraryproxymodel.h"
|
||||
#include "albumsproxymodel.h"
|
||||
#include "playlistsproxymodel.h"
|
||||
#include "dirviewmodel.h"
|
||||
#include "dirviewproxymodel.h"
|
||||
|
||||
class MPDBackend : public QObject
|
||||
{
|
||||
@@ -60,6 +62,7 @@ class MPDBackend : public QObject
|
||||
Q_PROPERTY(QString playQueueStatus READ getPlayQueueStatus NOTIFY onPlayQueueChanged)
|
||||
Q_PROPERTY(bool artistsFound READ getArtistsFound NOTIFY onArtistsModelChanged)
|
||||
Q_PROPERTY(bool albumsFound READ getAlbumsFound NOTIFY onAlbumsModelChanged)
|
||||
Q_PROPERTY(bool foldersFound READ getFoldersFound NOTIFY onFoldersModelChanged)
|
||||
Q_PROPERTY(bool playlistsFound READ getPlaylistsFound NOTIFY onPlaylistsModelChanged)
|
||||
|
||||
public:
|
||||
@@ -87,6 +90,7 @@ public:
|
||||
Q_INVOKABLE bool isPlayQueueEmpty() { return playQueueModel.rowCount() == 0; }
|
||||
Q_INVOKABLE bool getArtistsFound() { return MusicLibraryModel::self()->rowCount()>0; }
|
||||
Q_INVOKABLE bool getAlbumsFound() { return AlbumsModel::self()->rowCount()>0; }
|
||||
Q_INVOKABLE bool getFoldersFound() { return DirViewModel::self()->rowCount()>0; }
|
||||
Q_INVOKABLE bool getPlaylistsFound() { return PlaylistsModel::self()->rowCount()>0; }
|
||||
Q_INVOKABLE bool getIsRandomOrder() { return MPDStatus::self()->random(); }
|
||||
Q_INVOKABLE void setIsRandomOrder(bool random);
|
||||
@@ -94,6 +98,7 @@ public:
|
||||
PlayQueueProxyModel * getPlayQueueProxyModel() { return &playQueueProxyModel; }
|
||||
MusicLibraryProxyModel * getArtistsProxyModel() { return &artistsProxyModel; }
|
||||
AlbumsProxyModel * getAlbumsProxyModel() { return &albumsProxyModel; }
|
||||
DirViewProxyModel * getFoldersProxyModel() { return &foldersProxyModel; }
|
||||
PlaylistsProxyModel * getPlaylistsProxyModel() { return &playlistsProxyModel; }
|
||||
|
||||
Q_SIGNALS:
|
||||
@@ -103,6 +108,7 @@ Q_SIGNALS:
|
||||
void onPlayQueueChanged();
|
||||
void onArtistsModelChanged();
|
||||
void onAlbumsModelChanged();
|
||||
void onFoldersModelChanged();
|
||||
void onPlaylistsModelChanged();
|
||||
void onMpdStatusChanged();
|
||||
|
||||
@@ -115,6 +121,7 @@ public Q_SLOTS:
|
||||
void mpdConnectionStateChanged(bool connected);
|
||||
void artistsUpdated();
|
||||
void albumsUpdated();
|
||||
void foldersUpdated();
|
||||
void playlistsUpdated();
|
||||
|
||||
Q_SIGNALS:
|
||||
@@ -129,6 +136,7 @@ Q_SIGNALS:
|
||||
void startPlayingSongId(qint32);
|
||||
void goToNextSong();
|
||||
void goToPreviousSong();
|
||||
void loadFolders();
|
||||
void loadLibrary();
|
||||
void add(const QStringList &files, bool replace, quint8 priorty); // Songs
|
||||
void loadPlaylist(const QString &name, bool replace);
|
||||
@@ -154,6 +162,7 @@ private:
|
||||
PlayQueueProxyModel playQueueProxyModel;
|
||||
MusicLibraryProxyModel artistsProxyModel;
|
||||
AlbumsProxyModel albumsProxyModel;
|
||||
DirViewProxyModel foldersProxyModel;
|
||||
PlaylistsProxyModel playlistsProxyModel;
|
||||
};
|
||||
|
||||
|
||||
@@ -200,6 +200,7 @@ int main(int argc, char *argv[])
|
||||
view.rootContext()->setContextProperty("backend", &backend);
|
||||
view.rootContext()->setContextProperty("artistsProxyModel", backend.getArtistsProxyModel());
|
||||
view.rootContext()->setContextProperty("albumsProxyModel", backend.getAlbumsProxyModel());
|
||||
view.rootContext()->setContextProperty("foldersProxyModel", backend.getFoldersProxyModel());
|
||||
view.rootContext()->setContextProperty("playlistsProxyModel", backend.getPlaylistsProxyModel());
|
||||
view.rootContext()->setContextProperty("playQueueProxyModel", backend.getPlayQueueProxyModel());
|
||||
view.rootContext()->setContextProperty("currentCover", CurrentCover::self());
|
||||
@@ -207,8 +208,5 @@ int main(int argc, char *argv[])
|
||||
view.setResizeMode(QQuickView::SizeRootObjectToView);
|
||||
view.setSource(QUrl("qrc:qml/cantata/main.qml"));
|
||||
view.show();
|
||||
|
||||
AlbumsModel::self()->setEnabled(true);
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ Page {
|
||||
visible: false
|
||||
|
||||
property variant rows
|
||||
property int depth: -1
|
||||
property string modelName
|
||||
property alias model: visualDataModel.model
|
||||
|
||||
@@ -56,26 +55,23 @@ Page {
|
||||
}
|
||||
|
||||
function onDelegateClicked(index, text) {
|
||||
if (depth > 1) {
|
||||
var newRows = []
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
newRows[i] = rows[i]
|
||||
}
|
||||
newRows[rows.length] = index
|
||||
var newRows = []
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
newRows[i] = rows[i]
|
||||
}
|
||||
newRows[rows.length] = index
|
||||
|
||||
var component = Qt.createComponent("SubListViewPage.qml")
|
||||
var component = Qt.createComponent("SubListViewPage.qml")
|
||||
|
||||
if (component.status == Component.Ready) {
|
||||
var page = component.createObject(parent, {"model": model, "title": text, "modelName": modelName})
|
||||
page.init(newRows, depth - 1)
|
||||
pageStack.push(page)
|
||||
}
|
||||
if (component.status == Component.Ready) {
|
||||
var page = component.createObject(parent, {"model": model, "title": text, "modelName": modelName})
|
||||
page.init(newRows)
|
||||
pageStack.push(page)
|
||||
}
|
||||
}
|
||||
|
||||
function init(rows, depth) {
|
||||
function init(rows) {
|
||||
this.rows = rows
|
||||
this.depth = depth
|
||||
subListView.model.rootIndex = -1
|
||||
for (var i = 0; i < this.rows.length; i++) {
|
||||
subListView.model.rootIndex = subListView.model.modelIndex(this.rows[i])
|
||||
@@ -155,7 +151,7 @@ Page {
|
||||
onFirstImageButtonClicked: subListViewPage.add(index, true)
|
||||
onSecondImageButtonClicked: subListViewPage.add(index, false)
|
||||
|
||||
onClicked: subListViewPage.onDelegateClicked(index, model.titleText)
|
||||
onClicked: model.hasChildren ? subListViewPage.onDelegateClicked(index, model.titleText) : "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ MainView {
|
||||
var component = Qt.createComponent("SubListViewPage.qml")
|
||||
|
||||
var page = component.createObject(parent, {"model": model, "title": text, "modelName": "artists"})
|
||||
page.init([index], 2)
|
||||
page.init([index])
|
||||
pageStack.push(page)
|
||||
}
|
||||
}
|
||||
@@ -108,7 +108,34 @@ MainView {
|
||||
var component = Qt.createComponent("SubListViewPage.qml")
|
||||
|
||||
var page = component.createObject(parent, {"model": model, "title": text, "modelName": "albums"})
|
||||
page.init([index], 1)
|
||||
page.init([index])
|
||||
pageStack.push(page)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Tab {
|
||||
id: foldersTab
|
||||
title: i18n.tr("Folders")
|
||||
|
||||
page: ListViewPage {
|
||||
id: foldersPage
|
||||
|
||||
model: foldersProxyModel
|
||||
|
||||
emptyViewVisible: !backend.foldersFound
|
||||
emptyViewText: i18n.tr("No folders found")
|
||||
|
||||
function add(index, replace) {
|
||||
backend.add("folders", index, replace)
|
||||
pageStack.push(currentlyPlayingPage)
|
||||
}
|
||||
|
||||
function onDelegateClicked(index, text) {
|
||||
var component = Qt.createComponent("SubListViewPage.qml")
|
||||
|
||||
var page = component.createObject(parent, {"model": model, "title": text, "modelName": "folders"})
|
||||
page.init([index])
|
||||
pageStack.push(page)
|
||||
}
|
||||
}
|
||||
@@ -135,7 +162,7 @@ MainView {
|
||||
var component = Qt.createComponent("SubListViewPage.qml")
|
||||
|
||||
var page = component.createObject(parent, {"model": model, "title": text, "modelName": "playlists"})
|
||||
page.init([index], 1)
|
||||
page.init([index])
|
||||
pageStack.push(page)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user