defuze.me  Client
librarymodel.cpp
00001 #include "librarymodel.hpp"
00002 #include "library.hpp"
00003 #include "exception.hpp"
00004 #include "libraryitem.hpp"
00005 #include <QSqlRecord>
00006 #include <QStack>
00007 #include <QDebug>
00008 
00009 using namespace Library;
00010 
00011 LibraryModel::LibraryModel(LibraryPlugin *library) : TreeModel(), library(library)
00012 {
00013     currentSearch = "";
00014     initKeys();
00015 }
00016 
00017 void LibraryModel::initKeys()
00018 {
00019     sortKeysInfo[TRACK]  << "Track"  << "title"  << "track"  << "No title info";
00020     sortKeysInfo[TITLE]  << "Title"  << "title"  << "title"  << "No title info";
00021     sortKeysInfo[ALBUM]  << "Album"  << "album"  << "album"  << "Unknown Album";
00022     sortKeysInfo[ARTIST] << "Artist" << "artist" << "artist" << "Unknown Artist";
00023     sortKeysInfo[GENRE]  << "Genre"  << "genre"  << "genre"  << "Unknown Genre";
00024     sortKeysInfo[ALBUM_ARTIST] << "Artist" << "album_artist" << "album_artist" << "Unknown Artist";
00025     sortKeys << ALBUM_ARTIST << ALBUM << TRACK;
00026 }
00027 
00028 void LibraryModel::setupModelData()
00029 {
00030     update();
00031 }
00032 
00033 void LibraryModel::update(int sort, QString search)
00034 {
00035     QSqlQuery query;
00036 
00037     buildQuery(&query, sort, search);
00038     if (!query.exec())
00039         throw_exception(0x01, tr("Can't get AudioTracks from database: %1").arg(query.lastError().text()));
00040     clear();
00041     buildTree(&query, rootItem);
00042 }
00043 
00044 void LibraryModel::clear()
00045 {
00046     beginRemoveRows(QModelIndex(), 0, rootItem->childCount());
00047     delete rootItem;
00048     endRemoveRows();
00049     QList<QVariant> rootData;
00050     rootData << "1";
00051     rootItem = new TreeItem(rootData);
00052 }
00053 
00054 void LibraryModel::buildQuery(QSqlQuery *query, int sort, const QString &search)
00055 {
00056     QString searchWhere = "";
00057 
00058     if (!search.isNull())
00059         currentSearch = search;
00060     if (sort >= 0)
00061         updateSortKeys(sort);
00062     if (!(currentSearch.isNull() || currentSearch.isEmpty()))
00063         searchWhere = updateSearch();
00064     query->prepare("SELECT id, album_artist, artist, album, title, duration, genre "
00065                    "FROM audio_tracks " + searchWhere + "ORDER BY " + orderByKeys() + ";");
00066     if (!(searchWhere.isNull() || searchWhere.isEmpty()))
00067         for (int i = 0 ; i < sortKeys.size() ; ++i)
00068             query->bindValue(":search" + QVariant(i).toString(), "%" + currentSearch + "%");
00069 }
00070 
00071 void LibraryModel::buildTree(QSqlQuery *query, TreeItem *parent)
00072 {
00073     QStringList fields;
00074     QStack<TreeItem*> itemsStack;
00075 
00076     for (int i = 0 ; i < sortKeys.size() ; ++i)
00077         fields << QString();
00078     while (query->next())
00079     {
00080         foreach (SortKeys key , sortKeys)
00081         {
00082             QString str = query->value(query->record().indexOf(sortKeysInfo[key][FIELD])).toString();
00083             if (str.isEmpty())
00084                 str = sortKeysInfo[key][DEFAULT];
00085             if (str.compare(fields[sortKeys.indexOf(key)], Qt::CaseInsensitive) || isLowestLevelSortKey(key))
00086             {
00087                 for (int i = sortKeys.indexOf(key) + 1 ; i < sortKeys.size() ; ++i)
00088                     fields[i] = QString();
00089                 while (itemsStack.size() > sortKeys.indexOf(key))
00090                     itemsStack.pop();
00091                 fields[sortKeys.indexOf(key)] = str;
00092                 if (itemsStack.isEmpty())
00093                     parent = rootItem;
00094                 else
00095                     parent = itemsStack.top();
00096                 LibraryItem *elem = new LibraryItem(str, query->value(0).toInt(), key, parent);
00097                 itemsStack.push(elem);
00098                 parent->appendChild(elem);
00099                 elem->setIndex(createIndex(elem->row(), 0, elem));
00100                 if (!(currentSearch.isNull() || currentSearch.isEmpty()))
00101                     if (str.contains(currentSearch, Qt::CaseInsensitive))
00102                     {
00103                         library->getWidget()->getTreeViewWidget()->setExpanded(elem->getIndex().parent(), true);
00104                         library->getWidget()->getTreeViewWidget()->setExpanded(elem->getIndex().parent().parent(), true);
00105                         //setElementAsSearchResult
00106                     }
00107                 //if (isLowestLevelSortKey(key))
00108                 idByIndexes[elem->getIndex()] = query->value(0).toInt();
00109                 kindByIndexes[elem->getIndex()] = key;
00110             }
00111         }
00112     }
00113 }
00114 
00115 QString LibraryModel::orderByKeys() const
00116 {
00117     QStringList orderByKeys;
00118 
00119     foreach (SortKeys key, sortKeys)
00120         orderByKeys << sortKeysInfo[key][ORDER_BY];
00121     return orderByKeys.join(", ");
00122 }
00123 
00124 bool LibraryModel::isLowestLevelSortKey(SortKeys key)
00125 {
00126     return (sortKeys.indexOf(key) == (sortKeys.size() - 1));
00127 }
00128 
00129 void LibraryModel::updateSortKeys(int sort)
00130 {
00131     sortKeys.clear();
00132     if (sort == 1)
00133         sortKeys << ALBUM_ARTIST << TITLE;
00134     else if (sort == 2)
00135         sortKeys << GENRE << ARTIST << TITLE;
00136     else if (sort == 3)
00137         sortKeys << GENRE << TITLE;
00138     else
00139         sortKeys << ALBUM_ARTIST << ALBUM << TRACK;
00140 
00141 }
00142 
00143 QString LibraryModel::updateSearch()
00144 {
00145     QString like = " LIKE :search";
00146     QStringList fields;
00147     int i = 0;
00148 
00149     foreach (SortKeys key, sortKeys)
00150     {
00151         fields << sortKeysInfo[key][FIELD] + like + QVariant(i).toString() + " ";
00152         ++i;
00153     }
00154     return QString("WHERE (") + fields.join(" OR ") + QString(") ");
00155 }
00156 
00157 QStringList LibraryModel::mimeTypes() const
00158 {
00159     QStringList types;
00160     types << "application/x-defuzeme-audiotrack";
00161     return types;
00162 }
00163 
00164 QMimeData *LibraryModel::mimeData(const QModelIndexList &indexes) const
00165 {
00166     QMimeData *mimeData = new QMimeData();
00167     QByteArray encodedData;
00168     QDataStream stream(&encodedData, QIODevice::WriteOnly);
00169     QModelIndex index;
00170 
00171     if (indexes.length() >= 1)
00172         index = indexes.first();
00173     //foreach (const QModelIndex &index, indexes) {
00174     if (index.isValid()) {
00175         stream << getIdByIndex(index);
00176     }
00177     //}
00178     LibraryModel::SortKeys key = kindByIndexes[index];
00179     if (key == LibraryModel::TRACK || key == LibraryModel::TITLE)
00180         mimeData->setData("application/x-defuzeme-audiotrack", encodedData);
00181     else if (key == LibraryModel::ALBUM_ARTIST || key == LibraryModel::ARTIST)
00182         mimeData->setData("application/x-defuzeme-artist", encodedData);
00183     else if (key == LibraryModel::ALBUM)
00184         mimeData->setData("application/x-defuzeme-album", encodedData);
00185     else if (key == LibraryModel::GENRE)
00186         mimeData->setData("application/x-defuzeme-genre", encodedData);
00187     else
00188         mimeData->setData("application/x-defuzeme-invalid", encodedData);
00189     return mimeData;
00190 }
00191 
00192 Qt::ItemFlags LibraryModel::flags(const QModelIndex &index) const
00193 {
00194     if (!index.isValid())
00195         return 0;
00196     return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
00197 }
00198 
00199 QVariant LibraryModel::data(const QModelIndex &index, int role) const
00200 {
00201     if (!index.isValid())
00202         return QVariant();
00203 
00204     if (role != Qt::DisplayRole)
00205         return QVariant();
00206 
00207     LibraryItem *item = static_cast<LibraryItem*>(index.internalPointer());
00208 
00209     if (role == Qt::ToolTipRole)
00210         return item->data(index.column());
00211 
00212     return qVariantFromValue((void*)item);
00213 }
00214 
00215 int LibraryModel::getIdByIndex(const QModelIndex &index) const
00216 {
00217     if (idByIndexes.contains(index))
00218         return idByIndexes[index];
00219     else
00220         return 0;
00221 }
00222 
00223 LibraryModel::SortKeys LibraryModel::getKindByIndex(const QModelIndex &index) const
00224 {
00225     if (kindByIndexes.contains(index))
00226         return kindByIndexes[index];
00227     else
00228         return LibraryModel::INVALID;
00229 }
00230 
00231 LibraryPlugin *LibraryModel::getLibrary() const
00232 {
00233     return library;
00234 }