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