1
/* This file is part of Clementine.
2
Copyright 2010, David Sansome <me@davidsansome.com>
4
Clementine is free software: you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation, either version 3 of the License, or
7
(at your option) any later version.
9
Clementine is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
18
#include "icecastbackend.h"
19
#include "icecastmodel.h"
20
#include "playlist/songmimedata.h"
21
IcecastModel::IcecastModel(IcecastBackend* backend, QObject* parent)
22
: SimpleTreeModel<IcecastItem>(new IcecastItem(this), parent),
24
sort_mode_(SortMode_GenreByPopularity),
25
genre_icon_(":last.fm/icon_tag.png"),
26
station_icon_(":last.fm/icon_radio.png")
28
root_->lazy_loaded = true;
31
IcecastModel::~IcecastModel() {
35
void IcecastModel::Init() {
36
connect(backend_, SIGNAL(DatabaseReset()), SLOT(Reset()));
41
void IcecastModel::Reset() {
44
root_ = new IcecastItem(this);
45
root_->lazy_loaded = false;
52
void IcecastModel::LazyPopulate(IcecastItem* parent) {
53
if (parent->lazy_loaded)
55
parent->lazy_loaded = true;
57
switch (parent->type) {
58
case IcecastItem::Type_Station:
61
case IcecastItem::Type_Genre:
62
PopulateGenre(parent, parent->key, false);
65
case IcecastItem::Type_Root:
67
case SortMode_GenreAlphabetical:
68
AddGenres(backend_->GetGenresAlphabetical(filter_), true);
71
case SortMode_GenreByPopularity:
72
AddGenres(backend_->GetGenresByPopularity(filter_), false);
75
case SortMode_StationAlphabetical:
76
PopulateGenre(parent, QString(), true);
83
void IcecastModel::PopulateGenre(IcecastItem* parent, const QString& genre,
84
bool create_dividers) {
87
IcecastBackend::StationList stations = backend_->GetStations(filter_, genre);
88
foreach (const IcecastBackend::Station& station, stations) {
89
QChar divider_char = DividerKey(station.name);
90
if (create_dividers && !divider_char.isNull() && divider_char != last_divider) {
91
last_divider = divider_char;
93
IcecastItem* divider = new IcecastItem(IcecastItem::Type_Divider, parent);
94
divider->display_text = DividerDisplayText(divider_char);
95
divider->lazy_loaded = true;
98
IcecastItem* item = new IcecastItem(IcecastItem::Type_Station, parent);
99
item->station = station;
100
item->display_text = station.name;
101
item->sort_text = station.name;
102
item->key = station.url.toString();
103
item->lazy_loaded = true;
107
void IcecastModel::AddGenres(const QStringList& genres, bool create_dividers) {
110
foreach (const QString& genre, genres) {
111
QChar divider_char = DividerKey(genre);
112
if (create_dividers && divider_char != last_divider) {
113
last_divider = divider_char;
115
IcecastItem* divider = new IcecastItem(IcecastItem::Type_Divider, root_);
116
divider->display_text = DividerDisplayText(divider_char);
117
divider->lazy_loaded = true;
120
IcecastItem* item = new IcecastItem(IcecastItem::Type_Genre, root_);
125
QChar IcecastModel::DividerKey(const QString& text) {
134
if (c.isPunct() || c.isSymbol())
137
if (c.decompositionTag() != QChar::NoDecomposition)
138
return QChar(c.decomposition()[0]);
142
QString IcecastModel::DividerDisplayText(const QChar& key) {
148
QVariant IcecastModel::data(const QModelIndex& index, int role) const {
149
const IcecastItem* item = IndexToItem(index);
150
return data(item, role);
153
QVariant IcecastModel::data(const IcecastItem* item, int role) const {
155
case Qt::DisplayRole:
156
case Qt::ToolTipRole:
157
return item->DisplayText();
159
case Qt::DecorationRole:
160
switch (item->type) {
161
case IcecastItem::Type_Genre: return genre_icon_;
162
case IcecastItem::Type_Station: return station_icon_;
167
return item->type == IcecastItem::Type_Divider;
172
void IcecastModel::SetFilterText(const QString& filter) {
177
void IcecastModel::SetSortMode(SortMode mode) {
182
Qt::ItemFlags IcecastModel::flags(const QModelIndex& index) const {
183
switch (IndexToItem(index)->type) {
184
case IcecastItem::Type_Station:
185
return Qt::ItemIsSelectable |
187
Qt::ItemIsDragEnabled;
188
case IcecastItem::Type_Genre:
189
case IcecastItem::Type_Root:
190
case IcecastItem::Type_Divider:
192
return Qt::ItemIsEnabled;
196
QStringList IcecastModel::mimeTypes() const {
197
return QStringList() << "text/uri-list";
200
QMimeData* IcecastModel::mimeData(const QModelIndexList& indexes) const {
201
if (indexes.isEmpty())
204
SongMimeData* data = new SongMimeData;
207
foreach (const QModelIndex& index, indexes) {
208
IcecastItem* item = IndexToItem(index);
209
if (!item || item->type != IcecastItem::Type_Station)
212
data->songs << item->station.ToSong();
213
urls << item->station.url;
216
if (data->songs.isEmpty()) {
222
data->name_for_new_playlist_ = "Icecast";
227
Song IcecastModel::GetSong(const QModelIndex& index) const {
228
IcecastItem* item = IndexToItem(index);
229
if (!item || item->type != IcecastItem::Type_Station)
232
return item->station.ToSong();