~ubuntu-branches/ubuntu/saucy/clementine/saucy

« back to all changes in this revision

Viewing changes to src/radio/icecastmodel.cpp

  • Committer: Package Import Robot
  • Author(s): Thomas PIERSON
  • Date: 2012-01-01 20:43:39 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120101204339-lsb6nndwhfy05sde
Tags: 1.0.1+dfsg-1
New upstream release. (Closes: #653926, #651611, #657391)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* This file is part of Clementine.
2
 
   Copyright 2010, David Sansome <me@davidsansome.com>
3
 
 
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.
8
 
 
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.
13
 
 
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/>.
16
 
*/
17
 
 
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),
23
 
    backend_(backend),
24
 
    sort_mode_(SortMode_GenreByPopularity),
25
 
    genre_icon_(":last.fm/icon_tag.png"),
26
 
    station_icon_(":last.fm/icon_radio.png")
27
 
{
28
 
  root_->lazy_loaded = true;
29
 
}
30
 
 
31
 
IcecastModel::~IcecastModel() {
32
 
  delete root_;
33
 
}
34
 
 
35
 
void IcecastModel::Init() {
36
 
  connect(backend_, SIGNAL(DatabaseReset()), SLOT(Reset()));
37
 
 
38
 
  Reset();
39
 
}
40
 
 
41
 
void IcecastModel::Reset() {
42
 
  delete root_;
43
 
 
44
 
  root_ = new IcecastItem(this);
45
 
  root_->lazy_loaded = false;
46
 
 
47
 
  LazyPopulate(root_);
48
 
 
49
 
  reset();
50
 
}
51
 
 
52
 
void IcecastModel::LazyPopulate(IcecastItem* parent) {
53
 
  if (parent->lazy_loaded)
54
 
    return;
55
 
  parent->lazy_loaded = true;
56
 
 
57
 
  switch (parent->type) {
58
 
    case IcecastItem::Type_Station:
59
 
      return;
60
 
 
61
 
    case IcecastItem::Type_Genre:
62
 
      PopulateGenre(parent, parent->key, false);
63
 
      break;
64
 
 
65
 
    case IcecastItem::Type_Root:
66
 
      switch (sort_mode_) {
67
 
        case SortMode_GenreAlphabetical:
68
 
          AddGenres(backend_->GetGenresAlphabetical(filter_), true);
69
 
          break;
70
 
 
71
 
        case SortMode_GenreByPopularity:
72
 
          AddGenres(backend_->GetGenresByPopularity(filter_), false);
73
 
          break;
74
 
 
75
 
        case SortMode_StationAlphabetical:
76
 
          PopulateGenre(parent, QString(), true);
77
 
          break;
78
 
      }
79
 
      break;
80
 
  }
81
 
}
82
 
 
83
 
void IcecastModel::PopulateGenre(IcecastItem* parent, const QString& genre,
84
 
                                 bool create_dividers) {
85
 
  QChar last_divider;
86
 
 
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;
92
 
 
93
 
      IcecastItem* divider = new IcecastItem(IcecastItem::Type_Divider, parent);
94
 
      divider->display_text = DividerDisplayText(divider_char);
95
 
      divider->lazy_loaded = true;
96
 
    }
97
 
 
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;
104
 
  }
105
 
}
106
 
 
107
 
void IcecastModel::AddGenres(const QStringList& genres, bool create_dividers) {
108
 
  QChar last_divider;
109
 
 
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;
114
 
 
115
 
      IcecastItem* divider = new IcecastItem(IcecastItem::Type_Divider, root_);
116
 
      divider->display_text = DividerDisplayText(divider_char);
117
 
      divider->lazy_loaded = true;
118
 
    }
119
 
 
120
 
    IcecastItem* item = new IcecastItem(IcecastItem::Type_Genre, root_);
121
 
    item->key = genre;
122
 
  }
123
 
}
124
 
 
125
 
QChar IcecastModel::DividerKey(const QString& text) {
126
 
  if (text.isEmpty())
127
 
    return QChar();
128
 
 
129
 
  QChar c;
130
 
  c = text[0];
131
 
 
132
 
  if (c.isDigit())
133
 
    return '0';
134
 
  if (c.isPunct() || c.isSymbol())
135
 
    return QChar();
136
 
 
137
 
  if (c.decompositionTag() != QChar::NoDecomposition)
138
 
    return QChar(c.decomposition()[0]);
139
 
  return c.toUpper();
140
 
}
141
 
 
142
 
QString IcecastModel::DividerDisplayText(const QChar& key) {
143
 
  if (key == '0')
144
 
    return "0-9";
145
 
  return key;
146
 
}
147
 
 
148
 
QVariant IcecastModel::data(const QModelIndex& index, int role) const {
149
 
  const IcecastItem* item = IndexToItem(index);
150
 
  return data(item, role);
151
 
}
152
 
 
153
 
QVariant IcecastModel::data(const IcecastItem* item, int role) const {
154
 
  switch (role) {
155
 
    case Qt::DisplayRole:
156
 
    case Qt::ToolTipRole:
157
 
      return item->DisplayText();
158
 
 
159
 
    case Qt::DecorationRole:
160
 
      switch (item->type) {
161
 
        case IcecastItem::Type_Genre:   return genre_icon_;
162
 
        case IcecastItem::Type_Station: return station_icon_;
163
 
      }
164
 
      break;
165
 
 
166
 
    case Role_IsDivider:
167
 
      return item->type == IcecastItem::Type_Divider;
168
 
  }
169
 
  return QVariant();
170
 
}
171
 
 
172
 
void IcecastModel::SetFilterText(const QString& filter) {
173
 
  filter_ = filter;
174
 
  Reset();
175
 
}
176
 
 
177
 
void IcecastModel::SetSortMode(SortMode mode) {
178
 
  sort_mode_ = mode;
179
 
  Reset();
180
 
}
181
 
 
182
 
Qt::ItemFlags IcecastModel::flags(const QModelIndex& index) const {
183
 
  switch (IndexToItem(index)->type) {
184
 
  case IcecastItem::Type_Station:
185
 
    return Qt::ItemIsSelectable |
186
 
           Qt::ItemIsEnabled |
187
 
           Qt::ItemIsDragEnabled;
188
 
  case IcecastItem::Type_Genre:
189
 
  case IcecastItem::Type_Root:
190
 
  case IcecastItem::Type_Divider:
191
 
  default:
192
 
    return Qt::ItemIsEnabled;
193
 
  }
194
 
}
195
 
 
196
 
QStringList IcecastModel::mimeTypes() const {
197
 
  return QStringList() << "text/uri-list";
198
 
}
199
 
 
200
 
QMimeData* IcecastModel::mimeData(const QModelIndexList& indexes) const {
201
 
  if (indexes.isEmpty())
202
 
    return NULL;
203
 
 
204
 
  SongMimeData* data = new SongMimeData;
205
 
  QList<QUrl> urls;
206
 
 
207
 
  foreach (const QModelIndex& index, indexes) {
208
 
    IcecastItem* item = IndexToItem(index);
209
 
    if (!item || item->type != IcecastItem::Type_Station)
210
 
      continue;
211
 
 
212
 
    data->songs << item->station.ToSong();
213
 
    urls << item->station.url;
214
 
  }
215
 
 
216
 
  if (data->songs.isEmpty()) {
217
 
    delete data;
218
 
    return NULL;
219
 
  }
220
 
 
221
 
  data->setUrls(urls);
222
 
  data->name_for_new_playlist_ = "Icecast";
223
 
 
224
 
  return data;
225
 
}
226
 
 
227
 
Song IcecastModel::GetSong(const QModelIndex& index) const {
228
 
  IcecastItem* item = IndexToItem(index);
229
 
  if (!item || item->type != IcecastItem::Type_Station)
230
 
    return Song();
231
 
 
232
 
  return item->station.ToSong();
233
 
}