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 }