MythTV  0.26-pre
playlistcontainer.cpp
Go to the documentation of this file.
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             //  No, we don't destruct this ...
00141             temp_playlist->setParent(this);
00142             temp_playlist->loadPlaylistByID(query.value(0).toInt(), my_host);
00143             all_other_playlists->push_back(temp_playlist);
00144             //  ... cause it's sitting on this PtrList
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     //    Debugging
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     //  return a pointer to a playlist
00168     //  by id;
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     //  return a pointer to a playlist
00190     //  by name;
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     //  Need to touch the database to get persistent ID
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     //  Need to touch the database to get persistent ID
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     //  First, we need to take out any **track** on any other
00302     //  playlist that is actually a reference to this
00303     //  playlist
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     //FIXME remove this and the other post load stuff?
00358 
00359     //  Now that everything is loaded, we need to recheck all
00360     //  tracks and update those that refer to a playlist
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends