File indexing completed on 2025-01-05 04:25:21
0001 #include "tracksmodel.h" 0002 #include "db/collectionDB.h" 0003 0004 #include "vvave.h" 0005 #include "services/local/metadataeditor.h" 0006 0007 #include <MauiKit3/FileBrowsing/fmstatic.h> 0008 #include <MauiKit3/FileBrowsing/tagging.h> 0009 0010 #include <QTimer> 0011 0012 TracksModel::TracksModel(QObject *parent) 0013 : MauiList(parent) 0014 { 0015 qRegisterMetaType<TracksModel *>("const TracksModel*"); 0016 } 0017 0018 void TracksModel::componentComplete() 0019 { 0020 auto tracksTimer = new QTimer(this); 0021 tracksTimer->setSingleShot(true); 0022 tracksTimer->setInterval(1000); 0023 0024 connect(CollectionDB::getInstance(), &CollectionDB::trackInserted, [this, tracksTimer](QVariantMap) 0025 { 0026 m_newTracks++; 0027 tracksTimer->start(); 0028 }); 0029 0030 connect(tracksTimer, &QTimer::timeout, [this]() 0031 { 0032 if (m_newTracks > 0) 0033 { 0034 this->setList(); 0035 m_newTracks = 0; 0036 } 0037 }); 0038 0039 connect(this, &TracksModel::queryChanged, this, &TracksModel::setList); 0040 connect(vvave::instance(), &vvave::sourceRemoved, this, &TracksModel::setList); 0041 setList(); 0042 } 0043 0044 const FMH::MODEL_LIST &TracksModel::items() const 0045 { 0046 return this->list; 0047 } 0048 0049 void TracksModel::setQuery(const QString &query) 0050 { 0051 // if(this->query == query) 0052 // return; 0053 0054 this->query = query; 0055 Q_EMIT this->queryChanged(); 0056 } 0057 0058 QString TracksModel::getQuery() const 0059 { 0060 return this->query; 0061 } 0062 0063 int TracksModel::limit() const 0064 { 0065 return m_limit; 0066 } 0067 0068 void TracksModel::setList() 0069 { 0070 if (query.isEmpty()) 0071 return; 0072 0073 Q_EMIT this->preListChanged(); 0074 this->list.clear(); 0075 0076 qDebug() << "GETTIN TRACK LIST" << this->query; 0077 0078 if (this->query.startsWith("#")) 0079 { 0080 auto m_query = query; 0081 const auto urls = Tagging::getInstance()->getTagUrls(m_query.replace("#", ""), {}, true, m_limit, "audio"); 0082 for (const auto &url : urls) { 0083 this->list << CollectionDB::getInstance()->getDBData(QString("select t.* from tracks t inner join albums al on al.album = t.album " 0084 "and al.artist = t.artist where t.url = %1") 0085 .arg("\"" + url.toString() + "\"")); 0086 } 0087 0088 } else 0089 { 0090 this->list = CollectionDB::getInstance()->getDBData(this->query); 0091 } 0092 0093 Q_EMIT this->postListChanged(); 0094 Q_EMIT this->countChanged(); 0095 } 0096 0097 bool TracksModel::append(const QVariantMap &item) 0098 { 0099 if (item.isEmpty()) 0100 return false; 0101 0102 Q_EMIT this->preItemAppended(); 0103 this->list << FMH::toModel(item); 0104 Q_EMIT this->postItemAppended(); 0105 Q_EMIT this->countChanged(); 0106 0107 return true; 0108 } 0109 0110 bool TracksModel::appendUrl(const QUrl &url) 0111 { 0112 if (CollectionDB::getInstance()->check_existance(BAE::TABLEMAP[BAE::TABLE::TRACKS], FMH::MODEL_NAME[FMH::MODEL_KEY::URL], url.toString())) 0113 { 0114 const auto item = CollectionDB::getInstance()->getDBData(QStringList() << url.toString()); 0115 return append(FMH::toMap(item.first())); 0116 } else 0117 { 0118 return append(FMH::toMap(vvave::trackInfo(url))); 0119 } 0120 } 0121 0122 bool TracksModel::insertUrl(const QString &url, const int &index) 0123 { 0124 if (CollectionDB::getInstance()->check_existance(BAE::TABLEMAP[BAE::TABLE::TRACKS], FMH::MODEL_NAME[FMH::MODEL_KEY::URL], url)) 0125 { 0126 const auto item = CollectionDB::getInstance()->getDBData(QStringList() << url); 0127 return appendAt(FMH::toMap(item.first()), index); 0128 } else 0129 { 0130 return appendAt(FMH::toMap(vvave::trackInfo(url)), index); 0131 } 0132 } 0133 0134 bool TracksModel::insertUrls(const QStringList &urls, const int &index) 0135 { 0136 if(urls.isEmpty()) 0137 { 0138 return false; 0139 } 0140 0141 uint i = 0; 0142 for(const auto &url : urls) 0143 { 0144 qDebug() << "URLS OT INSERT" << url; 0145 0146 if(this->insertUrl(url, index+i)) 0147 { 0148 qDebug() << "URLS OT INSERT" << url; 0149 i++; 0150 } 0151 } 0152 0153 return true; 0154 } 0155 0156 bool TracksModel::appendUrls(const QStringList &urls) 0157 { 0158 for(const auto &url : urls) 0159 { 0160 this->appendUrl(url); 0161 } 0162 0163 return true; 0164 } 0165 0166 bool TracksModel::appendAt(const QVariantMap &item, const int &at) 0167 { 0168 if (item.isEmpty()) 0169 return false; 0170 0171 if (at > this->list.size() || at < 0) 0172 return false; 0173 0174 qDebug() << "trying to append at << " << 0; 0175 Q_EMIT this->preItemAppendedAt(at); 0176 this->list.insert(at, FMH::toModel(item)); 0177 Q_EMIT this->postItemAppended(); 0178 Q_EMIT this->countChanged(); 0179 return true; 0180 } 0181 0182 bool TracksModel::appendQuery(const QString &query) 0183 { 0184 Q_EMIT this->preListChanged(); 0185 this->list << CollectionDB::getInstance()->getDBData(query); 0186 Q_EMIT this->postListChanged(); 0187 Q_EMIT this->countChanged(); 0188 return true; 0189 } 0190 0191 void TracksModel::copy(const TracksModel *list) 0192 { 0193 if(!list) 0194 { 0195 return; 0196 } 0197 0198 Q_EMIT this->preItemsAppended(list->getCount()); 0199 this->list << list->items(); 0200 Q_EMIT this->postItemAppended(); 0201 Q_EMIT this->countChanged(); 0202 } 0203 0204 void TracksModel::clear() 0205 { 0206 Q_EMIT this->preListChanged(); 0207 this->list.clear(); 0208 Q_EMIT this->postListChanged(); 0209 Q_EMIT this->countChanged(); 0210 } 0211 0212 bool TracksModel::fav(const int &index, const bool &value) 0213 { 0214 if (index >= this->list.size() || index < 0) 0215 return false; 0216 0217 auto item = this->list[index]; 0218 0219 if (value) 0220 Tagging::getInstance()->fav(item[FMH::MODEL_KEY::URL]); 0221 else 0222 Tagging::getInstance()->unFav(item[FMH::MODEL_KEY::URL]); 0223 0224 return true; 0225 } 0226 0227 bool TracksModel::countUp(const int &index) 0228 { 0229 if (index >= this->list.size() || index < 0) 0230 return false; 0231 0232 qDebug() << "COUNT UP TRACK" << index; 0233 auto item = this->list[index]; 0234 if (CollectionDB::getInstance()->playedTrack(item[FMH::MODEL_KEY::URL])) { 0235 this->list[index][FMH::MODEL_KEY::COUNT] = QString::number(item[FMH::MODEL_KEY::COUNT].toInt() + 1); 0236 Q_EMIT this->updateModel(index, {FMH::MODEL_KEY::COUNT}); 0237 0238 return true; 0239 } 0240 0241 return false; 0242 } 0243 0244 bool TracksModel::remove(const int &index) 0245 { 0246 qDebug() << "REMOVE AT" << index; 0247 0248 if (index >= this->list.size() || index < 0) 0249 return false; 0250 0251 Q_EMIT this->preItemRemoved(index); 0252 this->list.removeAt(index); 0253 Q_EMIT this->postItemRemoved(); 0254 0255 return true; 0256 } 0257 0258 bool TracksModel::erase(const int &index) 0259 { 0260 qDebug() << "ERASE AT" << index; 0261 0262 if (index >= this->list.size() || index < 0) 0263 return false; 0264 auto url = this->list.at(index)[FMH::MODEL_KEY::URL]; 0265 0266 if(this->remove(index)) 0267 { 0268 return CollectionDB::getInstance()->removeTrack(url); 0269 } 0270 0271 return false; 0272 } 0273 0274 bool TracksModel::removeMissing(const int &index) 0275 { 0276 return erase(index); 0277 } 0278 0279 void TracksModel::refresh() 0280 { 0281 this->setList(); 0282 } 0283 0284 bool TracksModel::update(const QVariantMap &data, const int &index) 0285 { 0286 if (index >= this->list.size() || index < 0) 0287 return false; 0288 0289 auto newData = this->list[index]; 0290 QVector<int> roles; 0291 const auto keys = data.keys(); 0292 for (const auto &key : keys) 0293 { 0294 if (newData[FMH::MODEL_NAME_KEY[key]] != data[key].toString()) { 0295 newData.insert(FMH::MODEL_NAME_KEY[key], data[key].toString()); 0296 roles << FMH::MODEL_NAME_KEY[key]; 0297 } 0298 } 0299 0300 this->list[index] = newData; 0301 Q_EMIT this->updateModel(index, roles); 0302 return true; 0303 } 0304 0305 void TracksModel::updateMetadata(const QVariantMap &data, const int &index) 0306 { 0307 this->update(data, index); 0308 auto model = FMH::toModel(data); 0309 0310 MetadataEditor editor; 0311 editor.setUrl(model[FMH::MODEL_KEY::URL]); 0312 0313 editor.setTitle(model[FMH::MODEL_KEY::TITLE]); 0314 editor.setArtist(model[FMH::MODEL_KEY::ARTIST]); 0315 editor.setAlbum(model[FMH::MODEL_KEY::ALBUM]); 0316 editor.setYear(model[FMH::MODEL_KEY::RELEASEDATE].toInt()); 0317 editor.setGenre(model[FMH::MODEL_KEY::GENRE]); 0318 editor.setComment(model[FMH::MODEL_KEY::COMMENT]); 0319 editor.setTrack(model[FMH::MODEL_KEY::TRACK].toInt()); 0320 0321 auto n_model = FMH::filterModel(model, {FMH::MODEL_KEY::URL, FMH::MODEL_KEY::TITLE,FMH::MODEL_KEY::ARTIST,FMH::MODEL_KEY::ALBUM,FMH::MODEL_KEY::RELEASEDATE,FMH::MODEL_KEY::GENRE, FMH::MODEL_KEY::TRACK, FMH::MODEL_KEY::COMMENT}); 0322 0323 if(CollectionDB::getInstance()->updateTrack(n_model)) 0324 { 0325 qDebug() << "Track data was updated correctly"; 0326 } 0327 } 0328 0329 bool TracksModel::move(const int &index, const int &to) 0330 { 0331 if (index >= this->list.size() || index < 0) 0332 return false; 0333 0334 if (to >= this->list.size() || to < 0) 0335 return false; 0336 0337 this->list.move(index, to); 0338 Q_EMIT this->itemMoved(index, to); 0339 return true; 0340 } 0341 0342 QStringList TracksModel::urls() const 0343 { 0344 return FMH::modelToList(this->list, FMH::MODEL_KEY::URL); 0345 } 0346 0347 void TracksModel::setLimit(int limit) 0348 { 0349 if (m_limit == limit) 0350 return; 0351 0352 m_limit = limit; 0353 Q_EMIT limitChanged(m_limit); 0354 }