00001 #include <mythcontext.h>
00002 #include <mythdb.h>
00003 #include <compat.h>
00004
00005 #include "playlistcontainer.h"
00006 #include "mythlogging.h"
00007
00008 PlaylistLoadingThread::PlaylistLoadingThread(PlaylistContainer *parent_ptr,
00009 AllMusic *all_music_ptr) :
00010 MThread("PlaylistLoading"), parent(parent_ptr), all_music(all_music_ptr)
00011 {
00012 }
00013
00014 void PlaylistLoadingThread::run()
00015 {
00016 RunProlog();
00017 while (!all_music->doneLoading())
00018 {
00019 msleep(250);
00020 }
00021 parent->load();
00022 RunEpilog();
00023 }
00024
00025 #define LOC QString("PlaylistContainer: ")
00026 #define LOC_WARN QString("PlaylistContainer, Warning: ")
00027 #define LOC_ERR QString("PlaylistContainer, Error: ")
00028
00029 void PlaylistContainer::clearCDList()
00030 {
00031 cd_playlist.clear();
00032 }
00033
00034 void PlaylistContainer::addCDTrack(int track)
00035 {
00036 cd_playlist.push_back(track);
00037 }
00038
00039 void PlaylistContainer::removeCDTrack(int track)
00040 {
00041 cd_playlist.removeAll(track);
00042 }
00043
00044 bool PlaylistContainer::checkCDTrack(int track)
00045 {
00046 return cd_playlist.contains(track);
00047 }
00048
00049 PlaylistContainer::PlaylistContainer(
00050 AllMusic *all_music, const QString &host_name) :
00051 active_playlist(NULL), backup_playlist(NULL),
00052 stream_playlist(NULL),
00053 all_other_playlists(NULL), all_available_music(all_music),
00054 pending_writeback_index(-1),
00055
00056 playlists_loader(new PlaylistLoadingThread(this, all_music)),
00057 done_loading(false), my_host(host_name),
00058
00059 RatingWeight( gCoreContext->GetNumSetting("IntelliRatingWeight", 2)),
00060 PlayCountWeight(gCoreContext->GetNumSetting("IntelliPlayCountWeight", 2)),
00061 LastPlayWeight( gCoreContext->GetNumSetting("IntelliLastPlayWeight", 2)),
00062 RandomWeight( gCoreContext->GetNumSetting("IntelliRandomWeight", 2))
00063 {
00064 playlists_loader->start();
00065 }
00066
00067 PlaylistContainer::~PlaylistContainer()
00068 {
00069 playlists_loader->wait();
00070 delete playlists_loader;
00071 playlists_loader = NULL;
00072
00073 if (active_playlist)
00074 delete active_playlist;
00075 if (backup_playlist)
00076 delete backup_playlist;
00077 if (stream_playlist)
00078 delete stream_playlist;
00079 if (all_other_playlists)
00080 {
00081 while (!all_other_playlists->empty())
00082 {
00083 delete all_other_playlists->front();
00084 all_other_playlists->pop_front();
00085 }
00086 delete all_other_playlists;
00087 }
00088 }
00089
00090 void PlaylistContainer::FillIntelliWeights(int &rating, int &playcount,
00091 int &lastplay, int &random)
00092 {
00093 rating = RatingWeight;
00094 playcount = PlayCountWeight;
00095 lastplay = LastPlayWeight;
00096 random = RandomWeight;
00097 }
00098
00099 void PlaylistContainer::load()
00100 {
00101 done_loading = false;
00102 active_playlist = new Playlist();
00103 active_playlist->setParent(this);
00104
00105 backup_playlist = new Playlist();
00106 backup_playlist->setParent(this);
00107
00108 stream_playlist = new Playlist();
00109 stream_playlist->setParent(this);
00110
00111 all_other_playlists = new QList<Playlist*>;
00112
00113 cd_playlist.clear();
00114
00115 active_playlist->loadPlaylist("default_playlist_storage", my_host);
00116
00117 backup_playlist->loadPlaylist("backup_playlist_storage", my_host);
00118
00119 stream_playlist->loadPlaylist("stream_playlist", my_host);
00120
00121 MSqlQuery query(MSqlQuery::InitCon());
00122 query.prepare("SELECT playlist_id FROM music_playlists "
00123 "WHERE playlist_name != :DEFAULT"
00124 " AND playlist_name != :BACKUP "
00125 " AND (hostname = '' OR hostname = :HOST) "
00126 "ORDER BY playlist_name;");
00127 query.bindValue(":DEFAULT", "default_playlist_storage");
00128 query.bindValue(":BACKUP", "backup_playlist_storage");
00129 query.bindValue(":HOST", my_host);
00130
00131 if (!query.exec())
00132 {
00133 MythDB::DBError("Querying playlists", query);
00134 }
00135 else
00136 {
00137 while (query.next())
00138 {
00139 Playlist *temp_playlist = new Playlist();
00140
00141 temp_playlist->setParent(this);
00142 temp_playlist->loadPlaylistByID(query.value(0).toInt(), my_host);
00143 all_other_playlists->push_back(temp_playlist);
00144
00145 }
00146 }
00147 postLoad();
00148
00149 pending_writeback_index = 0;
00150
00151 int x = gCoreContext->GetNumSetting("LastMusicPlaylistPush");
00152 setPending(x);
00153 done_loading = true;
00154 }
00155
00156 void PlaylistContainer::describeYourself(void) const
00157 {
00158
00159 active_playlist->describeYourself();
00160 QList<Playlist*>::const_iterator it = all_other_playlists->begin();
00161 for (; it != all_other_playlists->end(); ++it)
00162 (*it)->describeYourself();
00163 }
00164
00165 Playlist *PlaylistContainer::getPlaylist(int id)
00166 {
00167
00168
00169
00170 if (active_playlist->getID() == id)
00171 {
00172 return active_playlist;
00173 }
00174
00175 QList<Playlist*>::iterator it = all_other_playlists->begin();
00176 for (; it != all_other_playlists->end(); ++it)
00177 {
00178 if ((*it)->getID() == id)
00179 return *it;
00180 }
00181
00182 LOG(VB_GENERAL, LOG_ERR,
00183 "getPlaylistName() called with unknown index number");
00184 return NULL;
00185 }
00186
00187 Playlist *PlaylistContainer::getPlaylist(const QString &name)
00188 {
00189
00190
00191
00192 QList<Playlist*>::iterator it = all_other_playlists->begin();
00193 for (; it != all_other_playlists->end(); ++it)
00194 {
00195 if ((*it)->getName() == name)
00196 return *it;
00197 }
00198
00199 LOG(VB_GENERAL, LOG_ERR, QString("getPlaylistName() called with unknown name: %1").arg(name));
00200 return NULL;
00201 }
00202
00203 void PlaylistContainer::save(void)
00204 {
00205 QList<Playlist*>::const_iterator it = all_other_playlists->begin();
00206 for (; it != all_other_playlists->end(); ++it)
00207 {
00208 if ((*it)->hasChanged())
00209 (*it)->savePlaylist((*it)->getName(), my_host);
00210 }
00211
00212 active_playlist->savePlaylist("default_playlist_storage", my_host);
00213 backup_playlist->savePlaylist("backup_playlist_storage", my_host);
00214 }
00215
00216 void PlaylistContainer::createNewPlaylist(QString name)
00217 {
00218 Playlist *new_list = new Playlist();
00219 new_list->setParent(this);
00220
00221
00222 new_list->savePlaylist(name, my_host);
00223 new_list->Changed();
00224 all_other_playlists->push_back(new_list);
00225 }
00226
00227 void PlaylistContainer::copyNewPlaylist(QString name)
00228 {
00229 Playlist *new_list = new Playlist();
00230 new_list->setParent(this);
00231
00232
00233 new_list->savePlaylist(name, my_host);
00234 new_list->Changed();
00235 all_other_playlists->push_back(new_list);
00236 active_playlist->copyTracks(new_list, false);
00237 pending_writeback_index = 0;
00238 }
00239
00240 void PlaylistContainer::popBackPlaylist()
00241 {
00242 Playlist *destination = getPlaylist(pending_writeback_index);
00243 if (!destination)
00244 {
00245 LOG(VB_GENERAL, LOG_WARNING, LOC + "popBackPlaylist() " +
00246 QString("Unknown playlist: %1") .arg(pending_writeback_index));
00247 return;
00248 }
00249 destination->removeAllTracks();
00250 destination->Changed();
00251 active_playlist->copyTracks(destination, false);
00252 active_playlist->removeAllTracks();
00253 backup_playlist->copyTracks(active_playlist, true);
00254 pending_writeback_index = 0;
00255
00256 active_playlist->Changed();
00257 backup_playlist->Changed();
00258 }
00259
00260 void PlaylistContainer::copyToActive(int index)
00261 {
00262 backup_playlist->removeAllTracks();
00263 active_playlist->copyTracks(backup_playlist, false);
00264
00265 pending_writeback_index = index;
00266
00267 active_playlist->removeAllTracks();
00268 Playlist *copy_from = getPlaylist(index);
00269 if (!copy_from)
00270 {
00271 LOG(VB_GENERAL, LOG_ERR, LOC + "copyToActive() " +
00272 QString("Unknown playlist: %1").arg(index));
00273 return;
00274 }
00275 copy_from->copyTracks(active_playlist, true);
00276
00277 active_playlist->Changed();
00278 backup_playlist->Changed();
00279 }
00280
00281
00282 void PlaylistContainer::renamePlaylist(int index, QString new_name)
00283 {
00284 Playlist *list_to_rename = getPlaylist(index);
00285 if (list_to_rename)
00286 {
00287 list_to_rename->setName(new_name);
00288 list_to_rename->Changed();
00289 }
00290 }
00291
00292 void PlaylistContainer::deletePlaylist(int kill_me)
00293 {
00294 Playlist *list_to_kill = getPlaylist(kill_me);
00295 if (!list_to_kill)
00296 {
00297 LOG(VB_GENERAL, LOG_ERR, LOC + "deletePlaylist() " +
00298 QString("Unknown playlist: %1").arg(kill_me));
00299 return;
00300 }
00301
00302
00303
00304
00305 if (kill_me == pending_writeback_index)
00306 popBackPlaylist();
00307
00308 active_playlist->removeTrack(kill_me * -1);
00309
00310 QList<Playlist*>::iterator it = all_other_playlists->begin();
00311 for (; it != all_other_playlists->end(); ++it)
00312 {
00313 if ((*it) != list_to_kill)
00314 (*it)->removeTrack(kill_me * -1);
00315 }
00316
00317 MSqlQuery query(MSqlQuery::InitCon());
00318 query.prepare("DELETE FROM music_playlists WHERE playlist_id = :ID ;");
00319 query.bindValue(":ID", kill_me);
00320
00321 if (!query.exec() || query.numRowsAffected() < 1)
00322 {
00323 MythDB::DBError("playlist delete", query);
00324 }
00325 list_to_kill->removeAllTracks();
00326 all_other_playlists->removeAll(list_to_kill);
00327 }
00328
00329
00330 QString PlaylistContainer::getPlaylistName(int index, bool &reference)
00331 {
00332 if (active_playlist)
00333 {
00334 if (active_playlist->getID() == index)
00335 {
00336 return active_playlist->getName();
00337 }
00338
00339 QList<Playlist*>::iterator it = all_other_playlists->begin();
00340 for (; it != all_other_playlists->end(); ++it)
00341 {
00342 if ((*it)->getID() == index)
00343 return (*it)->getName();
00344 }
00345 }
00346
00347 LOG(VB_GENERAL, LOG_ERR, LOC +
00348 "getPlaylistName() called with unknown index number");
00349
00350 reference = true;
00351 return QObject::tr("Something is Wrong");
00352 }
00353
00354
00355 void PlaylistContainer::postLoad()
00356 {
00357
00358
00359
00360
00361 #if 0
00362 active_playlist->postLoad();
00363 backup_playlist->postLoad();
00364
00365 QList<Playlist*>::iterator it = all_other_playlists->begin();
00366 for (; it != all_other_playlists->end(); ++it)
00367 (*it)->postLoad();
00368 #endif
00369 }
00370
00371 bool PlaylistContainer::pendingWriteback()
00372 {
00373 if (pending_writeback_index > 0)
00374 {
00375 return true;
00376 }
00377 return false;
00378 }
00379
00380 bool PlaylistContainer::nameIsUnique(QString a_name, int which_id)
00381 {
00382 if (a_name == "default_playlist_storage")
00383 return false;
00384
00385 if (a_name == "backup_playlist_storage")
00386 return false;
00387
00388 QList<Playlist*>::iterator it = all_other_playlists->begin();
00389 for (; it != all_other_playlists->end(); ++it)
00390 {
00391 if ((*it)->getName() == a_name && (*it)->getID() != which_id)
00392 return false;
00393 }
00394
00395 return true;
00396 }
00397
00398 QStringList PlaylistContainer::getPlaylistNames(void)
00399 {
00400 QStringList res;
00401
00402 QList<Playlist*>::iterator it = all_other_playlists->begin();
00403 for (; it != all_other_playlists->end(); ++it)
00404 {
00405 res.append((*it)->getName());
00406 }
00407
00408 return res;
00409 }
00410
00411 bool PlaylistContainer::cleanOutThreads()
00412 {
00413 if (playlists_loader->isFinished())
00414 {
00415 return true;
00416 }
00417 playlists_loader->wait();
00418 return false;
00419 }
00420
00421 void PlaylistContainer::clearActive()
00422 {
00423 backup_playlist->removeAllTracks();
00424 active_playlist->removeAllTracks();
00425 backup_playlist->Changed();
00426 active_playlist->Changed();
00427 pending_writeback_index = 0;
00428 }
00429