Refactor more common stuff out of the library model, and add a simple last.fm service
This commit is contained in:
parent
9b2a5b1535
commit
9430a8fd2f
@ -1,5 +1,5 @@
|
|||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/" >
|
<qresource prefix="/">
|
||||||
<file>clear.png</file>
|
<file>clear.png</file>
|
||||||
<file>go-home.png</file>
|
<file>go-home.png</file>
|
||||||
<file>go-next.png</file>
|
<file>go-next.png</file>
|
||||||
@ -33,5 +33,10 @@
|
|||||||
<file>exit.png</file>
|
<file>exit.png</file>
|
||||||
<file>copy.png</file>
|
<file>copy.png</file>
|
||||||
<file>move.png</file>
|
<file>move.png</file>
|
||||||
|
<file>last.fm/as.png</file>
|
||||||
|
<file>last.fm/loved_radio.png</file>
|
||||||
|
<file>last.fm/neighbour_radio.png</file>
|
||||||
|
<file>last.fm/personal_radio.png</file>
|
||||||
|
<file>last.fm/recommended_radio.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
BIN
data/last.fm/as.png
Normal file
BIN
data/last.fm/as.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
BIN
data/last.fm/loved_radio.png
Normal file
BIN
data/last.fm/loved_radio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 936 B |
BIN
data/last.fm/neighbour_radio.png
Normal file
BIN
data/last.fm/neighbour_radio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 637 B |
BIN
data/last.fm/personal_radio.png
Normal file
BIN
data/last.fm/personal_radio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 580 B |
BIN
data/last.fm/recommended_radio.png
Normal file
BIN
data/last.fm/recommended_radio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
36
src/lastfmservice.cpp
Normal file
36
src/lastfmservice.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "lastfmservice.h"
|
||||||
|
#include "radioitem.h"
|
||||||
|
|
||||||
|
LastFMService::LastFMService(QObject* parent)
|
||||||
|
: RadioService("Last.fm", parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RadioItem* LastFMService::CreateRootItem(RadioItem* parent) {
|
||||||
|
RadioItem* item = new RadioItem(this, RadioItem::Type_Service, "Last.fm", parent);
|
||||||
|
item->icon = QIcon(":last.fm/as.png");
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LastFMService::LazyPopulate(RadioItem *item) {
|
||||||
|
switch (item->type) {
|
||||||
|
case RadioItem::Type_Service:
|
||||||
|
CreateStationItem(Type_MyRecommendations, "My Recommendations",
|
||||||
|
":last.fm/recommended_radio.png", item);
|
||||||
|
CreateStationItem(Type_MyRadio, "My Radio Station",
|
||||||
|
":last.fm/personal_radio.png", item);
|
||||||
|
CreateStationItem(Type_MyLoved, "My Loved Tracks",
|
||||||
|
":last.fm/loved_radio.png", item);
|
||||||
|
CreateStationItem(Type_MyNeighbourhood, "My Neighbourhood",
|
||||||
|
":last.fm/neighbour_radio.png", item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RadioItem* LastFMService::CreateStationItem(ItemType type, const QString& name,
|
||||||
|
const QString& icon, RadioItem* parent) {
|
||||||
|
RadioItem* ret = new RadioItem(this, type, name, parent);
|
||||||
|
ret->lazy_loaded = true;
|
||||||
|
ret->icon = QIcon(icon);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
25
src/lastfmservice.h
Normal file
25
src/lastfmservice.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef LASTFMSERVICE_H
|
||||||
|
#define LASTFMSERVICE_H
|
||||||
|
|
||||||
|
#include "radioservice.h"
|
||||||
|
|
||||||
|
class LastFMService : public RadioService {
|
||||||
|
public:
|
||||||
|
LastFMService(QObject* parent = 0);
|
||||||
|
|
||||||
|
enum ItemType {
|
||||||
|
Type_MyRecommendations = 1000,
|
||||||
|
Type_MyRadio,
|
||||||
|
Type_MyLoved,
|
||||||
|
Type_MyNeighbourhood,
|
||||||
|
};
|
||||||
|
|
||||||
|
RadioItem* CreateRootItem(RadioItem* parent);
|
||||||
|
void LazyPopulate(RadioItem *item);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RadioItem* CreateStationItem(ItemType type, const QString& name,
|
||||||
|
const QString& icon, RadioItem* parent);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LASTFMSERVICE_H
|
@ -11,11 +11,10 @@
|
|||||||
|
|
||||||
|
|
||||||
Library::Library(EngineBase* engine, QObject* parent)
|
Library::Library(EngineBase* engine, QObject* parent)
|
||||||
: QAbstractItemModel(parent),
|
: SimpleTreeModel<LibraryItem>(new LibraryItem(LibraryItem::Type_Root), parent),
|
||||||
engine_(engine),
|
engine_(engine),
|
||||||
backend_(new BackgroundThread<LibraryBackend>(this)),
|
backend_(new BackgroundThread<LibraryBackend>(this)),
|
||||||
watcher_(new BackgroundThread<LibraryWatcher>(this)),
|
watcher_(new BackgroundThread<LibraryWatcher>(this)),
|
||||||
root_(new LibraryItem(LibraryItem::Type_Root)),
|
|
||||||
artist_icon_(":artist.png"),
|
artist_icon_(":artist.png"),
|
||||||
album_icon_(":album.png"),
|
album_icon_(":album.png"),
|
||||||
config_(new LibraryConfig)
|
config_(new LibraryConfig)
|
||||||
@ -280,22 +279,6 @@ void Library::SongsDeleted(const SongList& songs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LibraryItem* Library::IndexToItem(const QModelIndex& index) const {
|
|
||||||
if (!index.isValid())
|
|
||||||
return root_;
|
|
||||||
return reinterpret_cast<LibraryItem*>(index.internalPointer());
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex Library::ItemToIndex(LibraryItem* item) const {
|
|
||||||
if (!item || !item->parent)
|
|
||||||
return QModelIndex();
|
|
||||||
return createIndex(item->row, 0, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Library::columnCount(const QModelIndex &) const {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant Library::data(const QModelIndex& index, int role) const {
|
QVariant Library::data(const QModelIndex& index, int role) const {
|
||||||
const LibraryItem* item = IndexToItem(index);
|
const LibraryItem* item = IndexToItem(index);
|
||||||
|
|
||||||
@ -334,33 +317,6 @@ QVariant Library::data(const LibraryItem* item, int role) const {
|
|||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex Library::index(int row, int, const QModelIndex& parent) const {
|
|
||||||
LibraryItem* parent_item = IndexToItem(parent);
|
|
||||||
if (!parent_item || parent_item->children.count() <= row)
|
|
||||||
return QModelIndex();
|
|
||||||
|
|
||||||
return ItemToIndex(parent_item->children[row]);
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex Library::parent(const QModelIndex& index) const {
|
|
||||||
return ItemToIndex(IndexToItem(index)->parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Library::rowCount(const QModelIndex & parent) const {
|
|
||||||
LibraryItem* item = IndexToItem(parent);
|
|
||||||
const_cast<Library*>(this)->LazyPopulate(item); // Ahem
|
|
||||||
|
|
||||||
return item->children.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Library::hasChildren(const QModelIndex &parent) const {
|
|
||||||
LibraryItem* item = IndexToItem(parent);
|
|
||||||
if (item->lazy_loaded)
|
|
||||||
return !item->children.isEmpty();
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Library::LazyPopulate(LibraryItem* item) {
|
void Library::LazyPopulate(LibraryItem* item) {
|
||||||
if (item->lazy_loaded)
|
if (item->lazy_loaded)
|
||||||
return;
|
return;
|
||||||
|
@ -10,11 +10,12 @@
|
|||||||
#include "libraryquery.h"
|
#include "libraryquery.h"
|
||||||
#include "engine_fwd.h"
|
#include "engine_fwd.h"
|
||||||
#include "song.h"
|
#include "song.h"
|
||||||
|
#include "libraryitem.h"
|
||||||
|
#include "simpletreemodel.h"
|
||||||
|
|
||||||
class LibraryItem;
|
|
||||||
class LibraryConfig;
|
class LibraryConfig;
|
||||||
|
|
||||||
class Library : public QAbstractItemModel {
|
class Library : public SimpleTreeModel<LibraryItem> {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -34,12 +35,7 @@ class Library : public QAbstractItemModel {
|
|||||||
SongList GetChildSongs(const QModelIndex& index) const;
|
SongList GetChildSongs(const QModelIndex& index) const;
|
||||||
|
|
||||||
// QAbstractItemModel
|
// QAbstractItemModel
|
||||||
int columnCount(const QModelIndex & parent = QModelIndex()) const;
|
|
||||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||||
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
|
|
||||||
QModelIndex parent(const QModelIndex & index) const;
|
|
||||||
int rowCount(const QModelIndex & parent = QModelIndex()) const;
|
|
||||||
bool hasChildren(const QModelIndex &parent) const;
|
|
||||||
Qt::ItemFlags flags(const QModelIndex& index) const;
|
Qt::ItemFlags flags(const QModelIndex& index) const;
|
||||||
QStringList mimeTypes() const;
|
QStringList mimeTypes() const;
|
||||||
QMimeData* mimeData(const QModelIndexList& indexes) const;
|
QMimeData* mimeData(const QModelIndexList& indexes) const;
|
||||||
@ -54,6 +50,9 @@ class Library : public QAbstractItemModel {
|
|||||||
void SetFilterAge(int age);
|
void SetFilterAge(int age);
|
||||||
void SetFilterText(const QString& text);
|
void SetFilterText(const QString& text);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void LazyPopulate(LibraryItem* item);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// From LibraryBackend
|
// From LibraryBackend
|
||||||
void BackendInitialised();
|
void BackendInitialised();
|
||||||
@ -66,7 +65,6 @@ class Library : public QAbstractItemModel {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void Initialise();
|
void Initialise();
|
||||||
void LazyPopulate(LibraryItem* item);
|
|
||||||
|
|
||||||
LibraryItem* CreateCompilationArtistNode(bool signal);
|
LibraryItem* CreateCompilationArtistNode(bool signal);
|
||||||
LibraryItem* CreateArtistNode(bool signal, const QString& name);
|
LibraryItem* CreateArtistNode(bool signal, const QString& name);
|
||||||
@ -79,8 +77,6 @@ class Library : public QAbstractItemModel {
|
|||||||
QString SortTextForArtist(QString artist) const;
|
QString SortTextForArtist(QString artist) const;
|
||||||
QString SortTextForAlbum(QString album) const;
|
QString SortTextForAlbum(QString album) const;
|
||||||
|
|
||||||
LibraryItem* IndexToItem(const QModelIndex& index) const;
|
|
||||||
QModelIndex ItemToIndex(LibraryItem* item) const;
|
|
||||||
QVariant data(const LibraryItem* item, int role) const;
|
QVariant data(const LibraryItem* item, int role) const;
|
||||||
|
|
||||||
bool CompareItems(const LibraryItem* a, const LibraryItem* b) const;
|
bool CompareItems(const LibraryItem* a, const LibraryItem* b) const;
|
||||||
@ -94,7 +90,6 @@ class Library : public QAbstractItemModel {
|
|||||||
|
|
||||||
QueryOptions query_options_;
|
QueryOptions query_options_;
|
||||||
|
|
||||||
LibraryItem* root_;
|
|
||||||
QMap<int, LibraryItem*> song_nodes_;
|
QMap<int, LibraryItem*> song_nodes_;
|
||||||
QMap<QString, LibraryItem*> artist_nodes_;
|
QMap<QString, LibraryItem*> artist_nodes_;
|
||||||
QMap<QChar, LibraryItem*> divider_nodes_;
|
QMap<QChar, LibraryItem*> divider_nodes_;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "libraryconfig.h"
|
#include "libraryconfig.h"
|
||||||
#include "songplaylistitem.h"
|
#include "songplaylistitem.h"
|
||||||
#include "systemtrayicon.h"
|
#include "systemtrayicon.h"
|
||||||
|
#include "radiomodel.h"
|
||||||
|
|
||||||
#include <QFileSystemModel>
|
#include <QFileSystemModel>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
@ -25,6 +26,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
playlist_(new Playlist(this)),
|
playlist_(new Playlist(this)),
|
||||||
player_(new Player(playlist_, this)),
|
player_(new Player(playlist_, this)),
|
||||||
library_(new Library(player_->GetEngine(), this)),
|
library_(new Library(player_->GetEngine(), this)),
|
||||||
|
radio_model_(new RadioModel(this)),
|
||||||
library_sort_model_(new QSortFilterProxyModel(this)),
|
library_sort_model_(new QSortFilterProxyModel(this)),
|
||||||
tray_icon_(new SystemTrayIcon(this))
|
tray_icon_(new SystemTrayIcon(this))
|
||||||
{
|
{
|
||||||
@ -47,6 +49,8 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
ui_.library_view->setModel(library_sort_model_);
|
ui_.library_view->setModel(library_sort_model_);
|
||||||
ui_.library_view->SetLibrary(library_);
|
ui_.library_view->SetLibrary(library_);
|
||||||
|
|
||||||
|
ui_.radio_view->setModel(radio_model_);
|
||||||
|
|
||||||
// File view connections
|
// File view connections
|
||||||
connect(ui_.file_view, SIGNAL(Queue(QList<QUrl>)), SLOT(QueueFiles(QList<QUrl>)));
|
connect(ui_.file_view, SIGNAL(Queue(QList<QUrl>)), SLOT(QueueFiles(QList<QUrl>)));
|
||||||
connect(ui_.file_view, SIGNAL(PathChanged(QString)), SLOT(FilePathChanged(QString)));
|
connect(ui_.file_view, SIGNAL(PathChanged(QString)), SLOT(FilePathChanged(QString)));
|
||||||
|
@ -10,6 +10,7 @@ class Playlist;
|
|||||||
class Player;
|
class Player;
|
||||||
class Library;
|
class Library;
|
||||||
class LibraryConfig;
|
class LibraryConfig;
|
||||||
|
class RadioModel;
|
||||||
|
|
||||||
class QSortFilterProxyModel;
|
class QSortFilterProxyModel;
|
||||||
class SystemTrayIcon;
|
class SystemTrayIcon;
|
||||||
@ -57,6 +58,7 @@ class MainWindow : public QMainWindow {
|
|||||||
Playlist* playlist_;
|
Playlist* playlist_;
|
||||||
Player* player_;
|
Player* player_;
|
||||||
Library* library_;
|
Library* library_;
|
||||||
|
RadioModel* radio_model_;
|
||||||
|
|
||||||
QSortFilterProxyModel* library_sort_model_;
|
QSortFilterProxyModel* library_sort_model_;
|
||||||
|
|
||||||
|
@ -303,7 +303,41 @@
|
|||||||
<attribute name="dockWidgetArea">
|
<attribute name="dockWidgetArea">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
</attribute>
|
</attribute>
|
||||||
<widget class="QWidget" name="dockWidgetContents_5"/>
|
<widget class="QWidget" name="dockWidgetContents_5">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="margin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeView" name="radio_view">
|
||||||
|
<property name="dragEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="dragDropMode">
|
||||||
|
<enum>QAbstractItemView::DragOnly</enum>
|
||||||
|
</property>
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="uniformRowHeights">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="allColumnsShowFocus">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="headerHidden">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QDockWidget" name="files_dock">
|
<widget class="QDockWidget" name="files_dock">
|
||||||
<property name="features">
|
<property name="features">
|
||||||
|
8
src/radioitem.cpp
Normal file
8
src/radioitem.cpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "radioitem.h"
|
||||||
|
|
||||||
|
RadioItem::RadioItem(RadioService* _service, int type, const QString& key,
|
||||||
|
RadioItem* parent)
|
||||||
|
: SimpleTreeItem<RadioItem>(type, key, parent),
|
||||||
|
service(_service)
|
||||||
|
{
|
||||||
|
}
|
24
src/radioitem.h
Normal file
24
src/radioitem.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef RADIOITEM_H
|
||||||
|
#define RADIOITEM_H
|
||||||
|
|
||||||
|
#include <QIcon>
|
||||||
|
|
||||||
|
#include "simpletreeitem.h"
|
||||||
|
|
||||||
|
class RadioService;
|
||||||
|
|
||||||
|
class RadioItem : public SimpleTreeItem<RadioItem> {
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
Type_Root = 1,
|
||||||
|
Type_Service,
|
||||||
|
};
|
||||||
|
|
||||||
|
RadioItem(RadioService* _service, int type, const QString& key = QString::null,
|
||||||
|
RadioItem* parent = NULL);
|
||||||
|
|
||||||
|
QIcon icon;
|
||||||
|
RadioService* service;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RADIOITEM_H
|
45
src/radiomodel.cpp
Normal file
45
src/radiomodel.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "radiomodel.h"
|
||||||
|
#include "radioservice.h"
|
||||||
|
#include "lastfmservice.h"
|
||||||
|
|
||||||
|
RadioModel::RadioModel(QObject* parent)
|
||||||
|
: SimpleTreeModel<RadioItem>(new RadioItem(NULL, RadioItem::Type_Root), parent)
|
||||||
|
{
|
||||||
|
root_->lazy_loaded = true;
|
||||||
|
|
||||||
|
LastFMService* lastfm = new LastFMService(this);
|
||||||
|
services_ << lastfm;
|
||||||
|
lastfm->CreateRootItem(root_);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RadioModel::data(const QModelIndex& index, int role) const {
|
||||||
|
const RadioItem* item = IndexToItem(index);
|
||||||
|
|
||||||
|
return data(item, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RadioModel::data(const RadioItem* item, int role) const {
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
return item->DisplayText();
|
||||||
|
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
return item->icon;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Role_Type:
|
||||||
|
return item->type;
|
||||||
|
|
||||||
|
case Role_Key:
|
||||||
|
return item->key;
|
||||||
|
|
||||||
|
case Role_SortText:
|
||||||
|
return item->SortText();
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RadioModel::LazyPopulate(RadioItem* parent) {
|
||||||
|
if (parent->service)
|
||||||
|
parent->service->LazyPopulate(parent);
|
||||||
|
}
|
32
src/radiomodel.h
Normal file
32
src/radiomodel.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef RADIOMODEL_H
|
||||||
|
#define RADIOMODEL_H
|
||||||
|
|
||||||
|
#include "radioitem.h"
|
||||||
|
#include "simpletreemodel.h"
|
||||||
|
|
||||||
|
class RadioService;
|
||||||
|
|
||||||
|
class RadioModel : public SimpleTreeModel<RadioItem> {
|
||||||
|
public:
|
||||||
|
RadioModel(QObject* parent = 0);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
Role_Type = Qt::UserRole + 1,
|
||||||
|
Role_SortText,
|
||||||
|
Role_Key,
|
||||||
|
};
|
||||||
|
|
||||||
|
// QAbstractItemModel
|
||||||
|
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void LazyPopulate(RadioItem* parent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVariant data(const RadioItem* item, int role) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<RadioService*> services_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RADIOMODEL_H
|
7
src/radioservice.cpp
Normal file
7
src/radioservice.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "radioservice.h"
|
||||||
|
|
||||||
|
RadioService::RadioService(const QString& name, QObject *parent)
|
||||||
|
: QObject(parent),
|
||||||
|
name_(name)
|
||||||
|
{
|
||||||
|
}
|
23
src/radioservice.h
Normal file
23
src/radioservice.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef RADIOSERVICE_H
|
||||||
|
#define RADIOSERVICE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class RadioItem;
|
||||||
|
|
||||||
|
class RadioService : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
RadioService(const QString& name, QObject* parent = 0);
|
||||||
|
|
||||||
|
QString name() const { return name_; }
|
||||||
|
|
||||||
|
virtual RadioItem* CreateRootItem(RadioItem* parent) = 0;
|
||||||
|
virtual void LazyPopulate(RadioItem* item) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RADIOSERVICE_H
|
89
src/simpletreemodel.h
Normal file
89
src/simpletreemodel.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#ifndef SIMPLETREEMODEL_H
|
||||||
|
#define SIMPLETREEMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
class QModelIndex;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class SimpleTreeModel : public QAbstractItemModel {
|
||||||
|
public:
|
||||||
|
SimpleTreeModel(T* root = 0, QObject* parent = 0);
|
||||||
|
virtual ~SimpleTreeModel() {}
|
||||||
|
|
||||||
|
// QAbstractItemModel
|
||||||
|
int columnCount(const QModelIndex& parent) const;
|
||||||
|
QModelIndex index(int row, int, const QModelIndex& parent) const;
|
||||||
|
QModelIndex parent(const QModelIndex& index) const;
|
||||||
|
int rowCount(const QModelIndex& parent) const;
|
||||||
|
bool hasChildren(const QModelIndex& parent) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
T* IndexToItem(const QModelIndex& index) const;
|
||||||
|
QModelIndex ItemToIndex(T* item) const;
|
||||||
|
|
||||||
|
virtual void LazyPopulate(T* item) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
T* root_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
SimpleTreeModel<T>::SimpleTreeModel(T* root, QObject* parent)
|
||||||
|
: QAbstractItemModel(parent),
|
||||||
|
root_(root)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T* SimpleTreeModel<T>::IndexToItem(const QModelIndex& index) const {
|
||||||
|
if (!index.isValid())
|
||||||
|
return root_;
|
||||||
|
return reinterpret_cast<T*>(index.internalPointer());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
QModelIndex SimpleTreeModel<T>::ItemToIndex(T* item) const {
|
||||||
|
if (!item || !item->parent)
|
||||||
|
return QModelIndex();
|
||||||
|
return createIndex(item->row, 0, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
int SimpleTreeModel<T>::columnCount(const QModelIndex &) const {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
QModelIndex SimpleTreeModel<T>::index(int row, int, const QModelIndex& parent) const {
|
||||||
|
T* parent_item = IndexToItem(parent);
|
||||||
|
if (!parent_item || parent_item->children.count() <= row)
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
return ItemToIndex(parent_item->children[row]);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
QModelIndex SimpleTreeModel<T>::parent(const QModelIndex& index) const {
|
||||||
|
return ItemToIndex(IndexToItem(index)->parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
int SimpleTreeModel<T>::rowCount(const QModelIndex & parent) const {
|
||||||
|
T* item = IndexToItem(parent);
|
||||||
|
const_cast<SimpleTreeModel<T>*>(this)->LazyPopulate(item); // Ahem
|
||||||
|
|
||||||
|
return item->children.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool SimpleTreeModel<T>::hasChildren(const QModelIndex &parent) const {
|
||||||
|
T* item = IndexToItem(parent);
|
||||||
|
if (item->lazy_loaded)
|
||||||
|
return !item->children.isEmpty();
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SIMPLETREEMODEL_H
|
13
src/src.pro
13
src/src.pro
@ -32,7 +32,11 @@ SOURCES += main.cpp \
|
|||||||
libraryquery.cpp \
|
libraryquery.cpp \
|
||||||
fileview.cpp \
|
fileview.cpp \
|
||||||
fileviewlist.cpp \
|
fileviewlist.cpp \
|
||||||
playlistheader.cpp
|
playlistheader.cpp \
|
||||||
|
radioitem.cpp \
|
||||||
|
radioservice.cpp \
|
||||||
|
lastfmservice.cpp \
|
||||||
|
radiomodel.cpp
|
||||||
HEADERS += mainwindow.h \
|
HEADERS += mainwindow.h \
|
||||||
player.h \
|
player.h \
|
||||||
library.h \
|
library.h \
|
||||||
@ -63,7 +67,12 @@ HEADERS += mainwindow.h \
|
|||||||
fileview.h \
|
fileview.h \
|
||||||
fileviewlist.h \
|
fileviewlist.h \
|
||||||
playlistheader.h \
|
playlistheader.h \
|
||||||
simpletreeitem.h
|
simpletreeitem.h \
|
||||||
|
radioitem.h \
|
||||||
|
radioservice.h \
|
||||||
|
lastfmservice.h \
|
||||||
|
simpletreemodel.h \
|
||||||
|
radiomodel.h
|
||||||
FORMS += mainwindow.ui \
|
FORMS += mainwindow.ui \
|
||||||
libraryconfig.ui \
|
libraryconfig.ui \
|
||||||
fileview.ui
|
fileview.ui
|
||||||
|
Loading…
x
Reference in New Issue
Block a user