defuze.me
Client
|
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 ¶meterIndex) 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 }