defuze.me  Client
listsmodel.cpp
00001 /**************************************************************************
00002 ** defuze.me Epitech Innovative Project
00003 **
00004 ** Copyright 2010-2012
00005 **   Athena Calmettes - Jocelyn De La Rosa - Francois Gaillard
00006 **   Adrien Jarthon - Alexandre Moore - Luc Peres - Arnaud Sellier
00007 **
00008 ** All rights reserved.
00009 **************************************************************************/
00010 
00011 #include "listsmodel.hpp"
00012 #include "listsplugin.hpp"
00013 #include "editabletreeitem.hpp"
00014 #include "audiotrack.hpp"
00015 #include "QVariantMap"
00016 
00017 using namespace Lists;
00018 
00019 ListsModel::ListsModel(ListsPlugin *lists) : EditableTreeModel(), lists(lists)
00020 {
00021     rootItem = new ListsItem("One", QPixmap(), this);
00022     setupModelData();
00023     connect(this, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataHaveChanged(QModelIndex,QModelIndex)));
00024     connect(lists->getWidget()->getTreeViewWidget(), SIGNAL(deleteElements()), this, SLOT(dataDeleted()));
00025 }
00026 
00027 ListsModel::~ListsModel()
00028 {
00029 }
00030 
00031 void ListsModel::dataHaveChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
00032 {
00033     Q_UNUSED(bottomRight)
00034 
00035     if (!topLeft.isValid())
00036         return;
00037     updateDBFromTree(getItem(topLeft));
00038     emit playlistNameChanged(getItem(topLeft)->getId(), getItem(topLeft)->data(0).toString());
00039 }
00040 
00041 void ListsModel::dataDeleted()
00042 {
00043     foreach(const QModelIndex &index, lists->getWidget()->getTreeViewWidget()->selectionModel()->selectedIndexes())
00044     {
00045         if (!index.isValid())
00046             return;
00047         ListsItem *item = getItem(index);
00048         if (item->isOfKind(ListsItem::PLAYLIST))
00049             removeList(index);
00050         else if (item->isOfKind(ListsItem::SEPARATOR))
00051             removeSeparatorFromList(index);
00052         else if (item->isOfKind(ListsItem::PARAMETER))
00053             removeParameterFromList(index);
00054     }
00055 }
00056 
00057 void ListsModel::removeList(const QModelIndex &listIndex)
00058 {
00059     ListsItem *item = getItem(listIndex);
00060     int id = item->getId();
00061     if (!item->isOfKind(ListsItem::PLAYLIST))
00062         return;
00063     removeRows(listIndex.row(), 1, listIndex.parent());
00064     QSqlQuery query;
00065     query.prepare("DELETE FROM playlists WHERE id = :id");
00066     query.bindValue("id", item->getId());
00067     query.exec();
00068     emit playlistRemoved(id);
00069 }
00070 
00071 void ListsModel::removeSeparatorFromList(const QModelIndex &separatorIndex)
00072 {
00073     ListsItem *item = getItem(separatorIndex);
00074     if (!item->isOfKind(ListsItem::SEPARATOR))
00075         return;
00076     if (item->parent()->childCount() == 1)
00077         removeList(separatorIndex.parent());
00078     else
00079     {
00080         removeRows(separatorIndex.row(), 1, separatorIndex.parent());
00081         updateDBFromTree(getItem(separatorIndex.parent()));
00082         emit playlistContentChanged(getItem(separatorIndex.parent())->getId());
00083     }
00084 }
00085 
00086 void ListsModel::removeParameterFromList(const QModelIndex &parameterIndex)
00087 {
00088     ListsItem *item = getItem(parameterIndex);
00089     if (!item->isOfKind(ListsItem::PARAMETER))
00090         return;
00091     if (item->parent()->childCount() == 1)
00092         if (item->isOfKind(ListsItem::PARAMETER, ListsItem::TRACK))
00093             removeList(parameterIndex.parent());
00094         else
00095             removeSeparatorFromList(parameterIndex.parent());
00096     else
00097     {
00098         removeRows(parameterIndex.row(), 1, parameterIndex.parent());
00099         if (item->isOfKind(ListsItem::PARAMETER, ListsItem::TRACK))
00100         {
00101             updateDBFromTree(getItem(parameterIndex.parent()));
00102             emit playlistContentChanged(getItem(parameterIndex.parent())->getId());
00103         }
00104         else
00105         {
00106             updateDBFromTree(getItem(parameterIndex.parent().parent()));
00107             emit playlistContentChanged(getItem(parameterIndex.parent().parent())->getId());
00108         }
00109     }
00110 }
00111 
00112 QVariant ListsModel::data(const QModelIndex &index, int role) const
00113 {
00114     if (role == Qt::ToolTipRole)
00115     {
00116         if (getItem(index)->isOfKind(ListsItem::PLAYLIST))
00117             return QVariant("Start typing to edit");
00118         else
00119             return QVariant();
00120     }
00121     else
00122         return EditableTreeModel::data(index, role);
00123 }
00124 
00125 ListsItem *ListsModel::getItem(const QModelIndex &index) const
00126 {
00127     if (index.isValid()) {
00128         ListsItem *item = static_cast<ListsItem*>(index.internalPointer());
00129         if (item) return item;
00130     }
00131     return getRootItem();
00132 }
00133 
00134 Qt::ItemFlags ListsModel::flags(const QModelIndex &index) const
00135 {
00136     if (!index.isValid())
00137         return 0;
00138 
00139     ListsItem *item = getItem(index);
00140     if (item->isOfKind(ListsItem::PLAYLIST))
00141         return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
00142     else
00143         return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
00144 }
00145 
00146 bool ListsModel::insertRows(int position, int rows, const QModelIndex &parent)
00147 {
00148     ListsItem *parentItem = static_cast<ListsItem*>(getItem(parent));
00149     bool success;
00150 
00151     beginInsertRows(parent, position, position + rows - 1);
00152     success = parentItem->insertChildren(position, rows, rootItem->columnCount());
00153     endInsertRows();
00154 
00155     return success;
00156 }
00157 
00158 void ListsModel::setupModelData()
00159 {
00160     dynamicItem = insertCategoryItem("Dynamic Playlists", ListsItem::DYNAMIC_PLAYLIST, 0);
00161     normalItem = insertCategoryItem("Normal Playlists", ListsItem::NORMAL_PLAYLIST, 0);
00162 
00163     insertAddItem("Drop here to create a normal playlist", ListsItem::ADD_NORMAL);
00164     insertAddItem("Drop here to create a dynamic playlist", ListsItem::ADD_DYNAMIC);
00165 
00166     updateTreeFromDB();
00167 }
00168 
00169 bool ListsModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
00170 {
00171     Q_UNUSED(action)
00172     Q_UNUSED(row)
00173     Q_UNUSED(column)
00174 
00175     ListsItem *item = getItem(lastDropIndex);
00176     ListsItem *parentItem = getItem(parent);
00177 
00178     if (item->isOfKind(ListsItem::ADD, ListsItem::ADD_DYNAMIC))
00179     {
00180         if (hasAction(item, data->formats(), CREATE_DYNAMIC_PLAYLIST))
00181             insertDynamicList(data, parentItem);
00182     }
00183     else if (item->isOfKind(ListsItem::PLAYLIST, ListsItem::NORMAL_PLAYLIST))
00184     {
00185         if (hasAction(item, data->formats(), ADD_TO_NORMAL_PLAYLIST))
00186             insertParametersInNormalList(data, item);
00187     }
00188     else if (item->isOfKind(ListsItem::PLAYLIST, ListsItem::DYNAMIC_PLAYLIST))
00189     {
00190         if (hasAction(item, data->formats(), ADD_TO_DYNAMIC_PLAYLIST))
00191             insertParametersInDynamicList(data, item);
00192     }
00193     else if (item->isOfKind(ListsItem::SEPARATOR))
00194     {
00195         if (hasAction(item, data->formats(), ADD_TO_DYNAMIC_PLAYLIST))
00196             insertParametersInDynamicList(data, parentItem);
00197     }
00198     else if (item->isOfKind(ListsItem::ADD, ListsItem::ADD_NORMAL))
00199     {
00200         if (hasAction(item, data->formats(), CREATE_NORMAL_PLAYLIST))
00201             insertNormalList(data, parentItem);
00202     }
00203     else
00204         return false;
00205     return true;
00206 }
00207 
00208 bool ListsModel::hasAction(ListsItem *item, const QStringList &formats, ListsModel::DropAction action)
00209 {
00210     DropAction defaultAction = getDropActionsForItem(item);
00211 
00212     if (defaultAction != INVALID_DROP_ACTION)
00213         if (defaultAction == action)
00214             return true;
00215     foreach (QString format, formats)
00216         if (getDropActionsForItem(item, format) == action)
00217             return true;
00218     return false;
00219 }
00220 
00221 ListsItem *ListsModel::insertCategoryItem(const QString &title, ListsItem::SubKind subKind, int position)
00222 {
00223     if (!getRootItem()->insertChildren(position, 1, 1))
00224         return 0;
00225     ListsItem *item = static_cast<ListsItem*>(rootItem->child(position));
00226     item->setKind(ListsItem::CATEGORY);
00227     item->setSubKind(subKind);
00228     item->setData(0, title);
00229     return item;
00230 }
00231 
00232 ListsItem *ListsModel::insertAddItem(const QString &title, ListsItem::SubKind subKind)
00233 {
00234     ListsItem *parentItem;
00235 
00236     if (subKind == ListsItem::ADD_NORMAL)
00237         parentItem = normalItem;
00238     else
00239         parentItem = dynamicItem;
00240     if (!parentItem->insertChildren(0, 1, 1))
00241         return 0;
00242     ListsItem *item = static_cast<ListsItem*>(parentItem->child(0));
00243     item->setKind(ListsItem::ADD);
00244     item->setSubKind(subKind);
00245     if (subKind == ListsItem::ADD_NORMAL)
00246     {
00247         dropTypesForItem[item] << "application/x-defuzeme-audiotrack";
00248         dropActionsForItem[item]["default"] = ListsModel::CREATE_NORMAL_PLAYLIST;
00249     }
00250     else
00251     {
00252         dropTypesForItem[item] << "application/x-defuzeme-genre";
00253         dropTypesForItem[item] << "application/x-defuzeme-album";
00254         dropTypesForItem[item] << "application/x-defuzeme-artist";
00255         dropActionsForItem[item]["default"] = ListsModel::CREATE_DYNAMIC_PLAYLIST;
00256     }
00257     item->setData(0, title);
00258     return item;
00259 }
00260 
00261 ListsItem *ListsModel::insertNormalList(const QMimeData *data, ListsItem *parentItem)
00262 {
00263     int position = parentItem->childCount();
00264     insertRows(position, 1, parentItem->index);
00265     ListsItem *item = parentItem->child(position);
00266     item->setKind(ListsItem::PLAYLIST);
00267     item->setSubKind(ListsItem::NORMAL_PLAYLIST);
00268     dropTypesForItem[item] << "application/x-defuzeme-audiotrack";
00269     dropActionsForItem[item]["default"] = ListsModel::ADD_TO_NORMAL_PLAYLIST;
00270     item->setData(0, "New Playlist");
00271     item->index = index(position, 0, parentItem->index);
00272 
00273     QSqlQuery query;
00274     query.prepare("INSERT INTO playlists(name, is_dynamic) VALUES (:name, :is_dynamic)");
00275     query.bindValue(":name", "New playlist");
00276     query.bindValue(":is_dynamic", false);
00277     query.exec();
00278     item->setId(query.lastInsertId().toInt());
00279 
00280     insertParametersInNormalList(data, item);
00281     lists->getWidget()->getTreeViewWidget()->setExpanded(item->index, true);
00282     lists->getWidget()->getTreeViewWidget()->setCurrentIndex(item->index);
00283     lists->getWidget()->getTreeViewWidget()->edit(item->index);
00284     return item;
00285 }
00286 
00287 void ListsModel::insertParametersInNormalList(const QMimeData *data, ListsItem *parentItem)
00288 {
00289     QByteArray  encodedData;
00290     ListsItem::SubKind subKind = ListsItem::INVALID_SUBKIND;
00291     if (data->hasFormat("application/x-defuzeme-audiotrack"))
00292     {
00293         encodedData = data->data("application/x-defuzeme-audiotrack");
00294         subKind = ListsItem::TRACK;
00295     }
00296     if (subKind == ListsItem::INVALID_SUBKIND)
00297         return;
00298     QDataStream stream(&encodedData, QIODevice::ReadOnly);
00299     QList<int> ids;
00300     while (!stream.atEnd())
00301     {
00302         int id;
00303         stream >> id;
00304         ids << id;
00305     }
00307     QList<int> existingTitles;
00308     for (int i = 0 ; i < parentItem->childCount() ; ++i)
00309         existingTitles << parentItem->child(i)->getId();
00310     for (int i = 0 ; i < ids.size() ; ++i)
00311     {
00312         Library::AudioTrack *audioTrack = Library::AudioTrack::getTrack(ids.at(i));
00313         if (!audioTrack)
00314             continue;
00315         QString title = audioTrack->getTitle();
00316         if (existingTitles.contains(ids.at(i)))
00317             continue;
00318         int p = parentItem->childCount();
00319         insertRows(p + i, 1, parentItem->index);
00320         ListsItem *paramItem = parentItem->child(p + i);
00321         paramItem->setId(ids.at(i));
00322         paramItem->setKind(ListsItem::PARAMETER);
00323         paramItem->setSubKind(subKind);
00324         paramItem->setData(0, title);
00325     }
00326     updateDBFromTree(parentItem);
00327     emit playlistContentChanged(parentItem->getId());
00328 }
00329 
00330 ListsItem *ListsModel::insertDynamicList(const QMimeData *data, ListsItem *parentItem)
00331 {
00332     int position = parentItem->childCount();
00333     if (!insertRows(position, 1, parentItem->index))
00334         return 0;
00335     ListsItem *item = static_cast<ListsItem*>(parentItem->child(position));
00336     item->setKind(ListsItem::PLAYLIST);
00337     item->setSubKind(ListsItem::DYNAMIC_PLAYLIST);
00338     dropTypesForItem[item] << "application/x-defuzeme-genre";
00339     dropTypesForItem[item] << "application/x-defuzeme-album";
00340     dropTypesForItem[item] << "application/x-defuzeme-artist";
00341     dropActionsForItem[item]["default"] = ListsModel::ADD_TO_DYNAMIC_PLAYLIST;
00342     item->setData(0, "New playlist");
00343     item->index = index(position, 0, parentItem->index);
00344 
00345     QSqlQuery query;
00346     query.prepare("INSERT INTO playlists(name, is_dynamic) VALUES (:name, :is_dynamic)");
00347     query.bindValue(":name", "New playlist");
00348     query.bindValue(":is_dynamic", true);
00349     query.exec();
00350     item->setId(query.lastInsertId().toInt());
00351 
00352     ListsItem *introItem = insertIntroItem(item);
00353 
00354     insertParametersInDynamicList(data, introItem);
00355 
00356     lists->getWidget()->getTreeViewWidget()->setExpanded(item->index, true);
00357     lists->getWidget()->getTreeViewWidget()->setExpanded(introItem->index, true);
00358     lists->getWidget()->getTreeViewWidget()->setCurrentIndex(item->index);
00359     lists->getWidget()->getTreeViewWidget()->edit(item->index);
00360 
00361     return item;
00362 }
00363 
00364 ListsItem *ListsModel::insertIntroItem(ListsItem *parentItem)
00365 {
00366     insertRows(0, 1, parentItem->index);
00367     ListsItem *introItem = static_cast<ListsItem*>(parentItem->child(0));
00368     introItem->setKind(ListsItem::SEPARATOR);
00369     introItem->setSubKind(ListsItem::INTRO);
00370     dropTypesForItem[introItem] << "application/x-defuzeme-genre";
00371     dropTypesForItem[introItem] << "application/x-defuzeme-album";
00372     dropTypesForItem[introItem] << "application/x-defuzeme-artist";
00373     dropActionsForItem[introItem]["default"] = ListsModel::ADD_TO_DYNAMIC_PLAYLIST;
00374     introItem->setData(0, "Songs");
00375     introItem->index = index(0, 0, parentItem->index);
00376     return introItem;
00377 }
00378 
00379 ListsItem *ListsModel::insertSeparatorItem(ListsItem::SubKind subKind, ListsItem *parentItem)
00380 {
00381     int position = parentItem->childCount();
00382     insertRows(position, 1, parentItem->index);
00383     ListsItem *sepItem = static_cast<ListsItem*>(parentItem->child(position));
00384     sepItem->setKind(ListsItem::SEPARATOR);
00385     sepItem->setSubKind(subKind);
00386     dropTypesForItem[sepItem] << "application/x-defuzeme-genre";
00387     dropTypesForItem[sepItem] << "application/x-defuzeme-album";
00388     dropTypesForItem[sepItem] << "application/x-defuzeme-artist";
00389     dropActionsForItem[sepItem]["default"] = ListsModel::ADD_TO_DYNAMIC_PLAYLIST;
00390     sepItem->setData(0, "And");
00391     sepItem->index = index(position, 0, parentItem->index);
00392     return sepItem;
00393 }
00394 
00395 void ListsModel::insertParametersInDynamicList(const QMimeData *data, ListsItem *parentItem)
00396 {
00397     QByteArray  encodedData;
00398     ListsItem::SubKind subKind = ListsItem::INVALID_SUBKIND;
00399     if (data->hasFormat("application/x-defuzeme-genre"))
00400     {
00401         encodedData = data->data("application/x-defuzeme-genre");
00402         subKind = ListsItem::GENRE;
00403     }
00404     else if (data->hasFormat("application/x-defuzeme-album"))
00405     {
00406         encodedData = data->data("application/x-defuzeme-album");
00407         subKind = ListsItem::ALBUM;
00408     }
00409     else if (data->hasFormat("application/x-defuzeme-artist"))
00410     {
00411         encodedData = data->data("application/x-defuzeme-artist");
00412         subKind = ListsItem::ARTIST;
00413     };
00414     if (subKind == ListsItem::INVALID_SUBKIND)
00415         return;
00416     QDataStream stream(&encodedData, QIODevice::ReadOnly);
00417     QList<int> ids;
00418     while (!stream.atEnd())
00419     {
00420         int id;
00421         stream >> id;
00422         ids << id;
00423     }
00425     ListsItem *separatorItem;
00426     ListsItem *listItem;
00427 
00428     if (parentItem->isOfKind(ListsItem::SEPARATOR))
00429     {
00430         separatorItem = parentItem;
00431         listItem = static_cast<ListsItem*>(parentItem->parent());
00432     }
00433     else if (parentItem->isOfKind(ListsItem::PLAYLIST, ListsItem::DYNAMIC_PLAYLIST))
00434     {
00435         listItem = parentItem;
00436         if (parentItem->childCount() == 0)
00437             separatorItem = insertIntroItem(parentItem);
00438         else
00439         {
00440             bool existingSeparator = false;
00441             for (int i = 0 ; i < parentItem->childCount() ; ++i)
00442             {
00443                 separatorItem = parentItem->child(i);
00444                 if (separatorItem->childCount() && separatorItem->child(0)->getSubKind() == subKind)
00445                 {
00446                     existingSeparator = true;
00447                     break;
00448                 }
00449             }
00450             if (!existingSeparator)
00451             {
00452                 separatorItem = insertSeparatorItem(ListsItem::AND, parentItem);
00453                 lists->getWidget()->getTreeViewWidget()->setExpanded(separatorItem->index, true);
00454             }
00455         }
00456     }
00457     else
00458         return;
00460     QStringList existingTitles;
00461     for (int i = 0 ; i < separatorItem->childCount() ; ++i)
00462         existingTitles << separatorItem->child(i)->data(0).toString();
00463     for (int i = 0 ; i < ids.size() ; ++i)
00464     {
00465         Library::AudioTrack *audioTrack = Library::AudioTrack::getTrack(ids.at(i));
00466         if (!audioTrack)
00467             continue;
00468         QString title;
00469         if (subKind == ListsItem::ARTIST)
00470             title = audioTrack->getAlbumArtist();
00471         else if (subKind == ListsItem::ALBUM)
00472             title = audioTrack->getAlbum();
00473         else if (subKind == ListsItem::GENRE)
00474             title = audioTrack->getGenre();
00475         if (existingTitles.contains(title, Qt::CaseInsensitive))
00476             continue;
00477         int p = separatorItem->childCount();
00478         insertRows(p + i, 1, separatorItem->index);
00479         ListsItem *paramItem = static_cast<ListsItem*>(separatorItem->child(p + i));
00480         paramItem->setId(ids.at(i));
00481         paramItem->setKind(ListsItem::PARAMETER);
00482         paramItem->setSubKind(subKind);
00483         paramItem->setData(0, title);
00484     }
00485     updateDBFromTree(listItem);
00486     emit playlistContentChanged(listItem->getId());
00487 }
00488 
00489 void ListsModel::updateDBFromTree(ListsItem *list) const
00490 {
00491     if (!list->isOfKind(ListsItem::PLAYLIST))
00492         return;
00493     if (list->isOfKind(ListsItem::PLAYLIST, ListsItem::NORMAL_PLAYLIST))
00494     {
00495         QList<QVariant> paramsList;
00496         for (int i = 0 ; i < list->childCount() ; ++i)
00497             paramsList << QVariant(list->child(i)->getId());
00498         QSqlQuery query;
00499         query.prepare("UPDATE playlists SET name = :name, definition = :definition WHERE id = :id");
00500         query.bindValue(":definition", Network::JsonParser().serialize(QVariant(paramsList)));
00501         query.bindValue(":name", list->data(0).toString());
00502         query.bindValue(":id", list->getId());
00503         query.exec();
00504 
00505     }
00506     else if (list->isOfKind(ListsItem::PLAYLIST, ListsItem::DYNAMIC_PLAYLIST))
00507     {
00508         QVariantMap map;
00509         QList<QVariant> separatorsList;
00510         map["id"] = list->getId();
00511         map["title"] = list->data(0);
00512         map["is_dynamic"] = true;
00513         for (int i = 0 ;  i < list->childCount() ; ++i)
00514         {
00515             ListsItem *separator = list->child(i);
00516             if (!separator->isOfKind(ListsItem::SEPARATOR))
00517                 continue;
00518 
00519             QMap<QString, QList<QVariant> > subMap;
00520             for (int j = 0 ; j < separator->childCount() ; ++j)
00521             {
00522                 ListsItem *parameter = separator->child(j);
00523                 QString subKindStr;
00524                 if (parameter->getSubKind() == ListsItem::GENRE)
00525                     subKindStr = "genres";
00526                 else if (parameter->getSubKind() == ListsItem::ALBUM)
00527                     subKindStr = "albums";
00528                 else if (parameter->getSubKind() == ListsItem::ARTIST)
00529                     subKindStr = "artists";
00530                 else
00531                     continue;
00532                 subMap[subKindStr] << QVariant(parameter->data(0));
00533             }
00534             QVariantMap variantSubMap;
00535             QMapIterator<QString, QList<QVariant> > it(subMap);
00536             while (it.hasNext()) {
00537                 it.next();
00538                 variantSubMap[it.key()] = QVariant(it.value());
00539             }
00540             separatorsList << variantSubMap;
00541         }
00542         map["separators"] = separatorsList;
00543         QSqlQuery query;
00544         query.prepare("UPDATE playlists SET name = :name, definition = :definition WHERE id = :id");
00545         query.bindValue(":definition", Network::JsonParser().serialize(QVariant(map)));
00546         query.bindValue(":name", map["title"]);
00547         query.bindValue(":id", list->getId());
00548         query.exec();
00549     }
00550 }
00551 
00552 void ListsModel::updateTreeFromDB()
00553 {
00554     QSqlQuery normalQuery;
00555     normalQuery.prepare("SELECT id, name, definition FROM playlists WHERE is_dynamic = 'false'");
00556     normalQuery.exec();
00557     while (normalQuery.next())
00558     {
00559         int id = normalQuery.value(0).toInt();
00560         QString name = normalQuery.value(1).toString();
00561         QList<QVariant> trackList = Network::JsonParser().parse(normalQuery.value(2).toByteArray()).toList();
00562 
00563         int p = normalItem->childCount();
00564         normalItem->insertChildren(p, 1, 1);
00565         ListsItem *item = normalItem->child(p);
00566         item->setKind(ListsItem::PLAYLIST);
00567         item->setSubKind(ListsItem::NORMAL_PLAYLIST);
00568         dropTypesForItem[item] << "application/x-defuzeme-audiotrack";
00569         dropActionsForItem[item]["default"] = ListsModel::ADD_TO_NORMAL_PLAYLIST;
00570         item->setId(id);
00571         item->setData(0, name);
00572 
00573         foreach (QVariant trackId, trackList)
00574         {
00575             Library::AudioTrack *audioTrack = Library::AudioTrack::getTrack(trackId.toInt());
00576             if (!audioTrack)
00577                 continue;
00578             int position = item->childCount();
00579             item->insertChildren(position, 1, 1);
00580             ListsItem *trackItem = item->child(position);
00581             trackItem->setKind(ListsItem::PARAMETER);
00582             trackItem->setSubKind(ListsItem::TRACK);
00583             trackItem->setId(trackId.toInt());
00584             trackItem->setData(0, audioTrack->getTitle());
00585         }
00586 
00587     }
00588 
00589     QSqlQuery query;
00590     query.prepare("SELECT id, definition FROM playlists WHERE is_dynamic = 'true'");
00591     query.exec();
00592     while (query.next())
00593     {
00594         int id = query.value(0).toInt();
00595         QVariantMap data = Network::JsonParser().parse(query.value(1).toByteArray()).toMap();
00596         if (data["id"] != id)
00597             continue;
00598         int p = dynamicItem->childCount();
00599         dynamicItem->insertChildren(p, 1, 1);
00600         ListsItem *item = dynamicItem->child(p);
00601         item->setKind(ListsItem::PLAYLIST);
00602         item->setSubKind(ListsItem::DYNAMIC_PLAYLIST);
00603         dropTypesForItem[item] << "application/x-defuzeme-genre";
00604         dropTypesForItem[item] << "application/x-defuzeme-album";
00605         dropTypesForItem[item] << "application/x-defuzeme-artist";
00606         dropActionsForItem[item]["default"] = ListsModel::ADD_TO_DYNAMIC_PLAYLIST;
00607         item->setId(id);
00608         item->setData(0, data["title"]);
00609 
00610         QList<QVariant> separators = data["separators"].toList();
00611         for (int i = 0 ; i < separators.size() ; ++i)
00612         {
00613             int position = item->childCount();
00614             item->insertChildren(position, 1, 1);
00615             ListsItem *sepItem = item->child(position);
00616             sepItem->setKind(ListsItem::SEPARATOR);
00617             dropTypesForItem[sepItem] << "application/x-defuzeme-genre";
00618             dropTypesForItem[sepItem] << "application/x-defuzeme-album";
00619             dropTypesForItem[sepItem] << "application/x-defuzeme-artist";
00620             dropActionsForItem[sepItem]["default"] = ListsModel::ADD_TO_DYNAMIC_PLAYLIST;
00621             if (i == 0)
00622             {
00623                 sepItem->setSubKind(ListsItem::INTRO);
00624                 sepItem->setData(0, "Songs");
00625             }
00626             else
00627             {
00628                 sepItem->setSubKind(ListsItem::AND);
00629                 sepItem->setData(0, "And");
00630             }
00631 
00632             QMap<QString, QVariant> paramsMap = separators.at(i).toMap();
00633             if (!paramsMap.size())
00634                 continue;
00635             QString subKindStr = paramsMap.keys().first();
00636             QList<QVariant> paramsList = paramsMap[subKindStr].toList();
00637             ListsItem::SubKind subKind;
00638             if (subKindStr == "artists")
00639                 subKind = ListsItem::ARTIST;
00640             else if (subKindStr == "albums")
00641                 subKind = ListsItem::ALBUM;
00642             else if (subKindStr == "genres")
00643                 subKind = ListsItem::GENRE;
00644             else
00645                 continue;
00646             foreach (QVariant param, paramsList)
00647             {
00648                 int pos = sepItem->childCount();
00649                 sepItem->insertChildren(pos, 1, 1);
00650                 ListsItem *paramItem = sepItem->child(pos);
00651                 paramItem->setKind(ListsItem::PARAMETER);
00652                 paramItem->setSubKind(subKind);
00653                 paramItem->setData(0, param.toString());
00654             }
00655         }
00656     }
00657 }
00658 
00659 ListsItem *ListsModel::getRootItem() const
00660 {
00661     return static_cast<ListsItem*>(rootItem);
00662 }
00663 
00664 QStringList ListsModel::getDropTypesForItem(ListsItem *item) const
00665 {
00666     return dropTypesForItem[item];
00667 }
00668 
00669 ListsModel::DropAction ListsModel::getDropActionsForItem(ListsItem *item, const QString &mimeType) const
00670 {
00671     if (dropActionsForItem[item].contains(mimeType))
00672         return dropActionsForItem[item][mimeType];
00673     else
00674         return ListsModel::INVALID_DROP_ACTION;
00675 }